[99s-extend] [cowboy REST] returning {true, URL} to PUT

Loïc Hoguin essen at ninenines.eu
Tue Jul 8 13:42:00 CEST 2014


That's what POST should do.

Compare:

PUT /some/resource/1234 -> no redirect needed
POST /some/resource -> creates /some/resource/1234, redirects

If /some/resource is a collection then PUT on that collection is 
supposed to replace it entirely.

Again it's possible for PUT to create a resource elsewhere, but 
typically the redirect would be from something like 
http://api.yourservice.com/resource/1234 to 
http://cloudthingy.server137.yourservice.com/whatever/resource/1234 and 
not to do what POST is intended for.

On 07/08/2014 01:32 PM, Samuel wrote:
> Ok, thanks. That should probably be mentioned in the documentation of
> content_types_accepted, as it says {true, URI} is a valid output for
> the provided function.
>
> Just out of curiosity from a non-so-expert in REST. The API spec
> (which I am not the author of) says the PUT call should create a
> resource with a unique id and return the URI of the created resource
> in the Location header. That is something like PUT /some/resource
> should return /some/resource/1234 in the Location. some/resource is
> fixed but 1234 would be generated for each instance of /some/resource.
> Is that considered nonsensical?
>
> On 8 July 2014 11:57, Loïc Hoguin <essen at ninenines.eu> wrote:
>> It's not enabled for PATCH or PUT because it makes little sense for them.
>> PATCH and PUT are typically used directly on the URI of the resource, even
>> when creating it. While you can return a "better URI" for the created
>> resource for them, this should be seen as a special case rather than the
>> norm. You can still do it by setting the location header manually and Cowboy
>> will react accordingly.
>>
>>
>> On 07/08/2014 09:12 AM, Samuel wrote:
>>>
>>> Hi,
>>>
>>> According to the documentation I should be able to return a new
>>> location when handling a PUT request when using cowboy_rest protocol:
>>>
>>>       The AcceptResource value is the name of the callback that will be
>>> called if the
>>>       content-type matches. It is defined as follow.
>>>
>>>       Value type: true | {true, URL} | false
>>>
>>> That works for "true" and "false" but not for "{true, URL}", in that
>>> case the Ranch listener crashes badly[1].
>>>
>>> Looking into cowboy_rest.erl I see that the {true, URL} form is
>>> restricted to POST requests:
>>> https://github.com/extend/cowboy/blob/master/src/cowboy_rest.erl#L784
>>>
>>> Is that intentional or should I submit a patch to add at least PUT and
>>> PATCH to that condition (or remove all of them if that is not guarding
>>> against something horrible)?
>>>
>>> Regards
>>>
>>> [1] Ranch crash log:
>>> Ranch listener http_acceptor had connection process started with
>>> cowboy_protocol:start_link/4 at <0.2660.0> exit with reason:
>>>
>>> {{case_clause,{{true,"/url"},{http_req,#Port<0.15864>,ranch_tcp,keepalive,<0.2660.0>,<<"PUT">>,'HTTP/1.1',{{127,0,0,1},56983},<<"localhost">>,undefined,8080,<<"/order">>,undefined,<<>>,undefined,[],[{<<"user-agent">>,<<"curl/7.22.0
>>> (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4
>>> libidn/1.23
>>> librtmp/2.3">>},{<<"host">>,<<"localhost:8080">>},{<<"accept">>,<<"*/*">>},{<<"content-type">>,<<"application/json">>}],[{<<"content-type">>,{<<"application">>,<<"json">>,[]}},{<<"if-modified-since">>,undefined},{<<"if-none-match">>,undefined},{<<"if-unmodified-since">>,undefined},{<<"if-match">>,undefined},{<<"accept">>,[{{<<"*">>,<<"*">>,[]},1000,[]}]}],undefined,[{charset,undefined},{media_type,{<<"text">>,<<"html">>,[]}}],waiting,undefined,<<>>,false,waiting,[{<<"content-type">>,[<<"text">>,<<"/">>,<<"html">>,<<>>]}],<<>>,undefined},{state}}},[{cowboy_rest,process_content_type,3,[{file,"src/cowboy_rest.erl"},{line,780}]},{cowboy_protocol,execute,4,[{file,"src/cowboy_protocol.erl"},{line,529}]}]}
>>>
>>
>> --
>> Loïc Hoguin
>> http://ninenines.eu
>
>
>

-- 
Loïc Hoguin
http://ninenines.eu


More information about the Extend mailing list