Rails respond_with — why does POST return a URL instead of the data?

前端 未结 3 605
甜味超标
甜味超标 2021-02-12 14:57

This is a question \"why does it work this way\", not \"how do I make this work\".

My app is calling a third party REST API that returns JSON, and returning the result a

3条回答
  •  余生分开走
    2021-02-12 15:37

    Summary: Rails gets its rationale from HTTP and REST.

    (Thanks for your updated question. Now I understand your core question: "I am not saying it's wrong, just trying to understand the rationale for the Rails implementation.")

    Now for the explanation. The rationale for how Rails behaves is rooted in embracing HTTP and REST conventions.

    Just to bridge from what you've read to what I'm about to elaborate on, I want to mention the relevant parts from Ryan Daigle's article on Default RESTful Rendering:

    If the :html format was requested:

    [some text removed]

    • [after PUT or POST and no validation errors] redirect to the resource location (i.e. user_url)

    (The text [in brackets] was added by me.)

    If another format was requested, (i.e. :xml or :json)

    [some text removed]

    • If it was a POST request, invoke the :to_format method on the resource and send that back with the :created status and the :location of the new created resource"

    Let me put this in my words about what Rails believes is good practice:

    • For human content (e.g. HTML), after a POST or PUT, the server should tell the browser to redirect via a 303 to the newly created resource. This is common practice -- a very useful thing because a user wants to see the updates resulting from their edits.

    • For machine content (e.g. JSON, XML), after a PUT, the server should just render a 201. The client, in this case, a program consuming an API, might decide to stop there. (After all, the client specified the request and got a 201, so all is honky dory.) This is why 201 (success), not 303 (redirect), is used. If the client wants to request the newly created resource, it can look it up using the Location header -- but a redirect should not be forced.

    In either case note that the location of the newly created resource is required. This is why @products in your example above needs to contain both the data and the location.

    For background, I've shared a little from the W3C Page on 201 Created:

    10.2.2 201 Created

    The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately, the server SHOULD respond with 202 (Accepted) response instead.

    I hope this helps to explain the rationale. It is my (naive?) understanding that this rationale is well accepted across Web frameworks. Historically, I suspect that Rails was the fervent implementation-ground (new word alert!) for many fervent supporters of REST and the Resource Oriented Architecture.

提交回复
热议问题