- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
- Providing a block of data, such as the result of submitting a
form, to a data-handling process;
- Extending a database through an append operation.It is clearly the third one that caused most of the confusion. However, it shouldn't have, if you read it closely. It says nothing of creating or updating a resource, but rather submitting data to a process. Which is exactly the sort of vague in-between-the-cracks sort of thing POST is meant for. Fielding elaborates in his most recent blog post: POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing." This can include updates to a resource when it applies to a "subordinate" part of it.
There is one circumstance that is slightly more complex
than the Twitter followers scenario -- which is certainly
a useful problem space to consider: even though Followers
are Users in their own right, just being a User does not
necessitate also being a Follower; ergo, the two can be
separated.
How about, though, something like a blog Article in some
article Index? We do in fact have (possibly) two separate
resources, and both of them are identifiable directly. In
such a case, it would be semantically correct to either PUT
Articles directly (creation/update does not matter), or to
POST through the Index. It could be argued that using PUT
would mean that Index does not "learn" about the Article,
but that implies a, well, implied relationship between the
two (which we want to usually avoid even if it actually
does exist.)
If both methods are valid, how to structure it so that it
does not allow (or discourages) duplication of logic? (E.g.
maybe a POST would do an internal PUT?)
And, if we should determine that only one of these methods
should be used in this situation, how would that be easily
communicable in constructing the resources?
And finally, how to best represent these in terms of links
and transitions?
It is (I guess) fine to say that the system is so flexible
that it allows both, but I have a hard time seeing value in
that -- there seems to be nothing *gained* by the option of
using either, except not having to agree on a convention. It
bothers me that REST is so very ill-defined in some respects
and often some of the explanations sound like so much hand-
wavy BS; sometimes HTTP matters, but hey, sometimes it does
not. It is quite possible that I am just not smart enough
to get these radical ideas, but it seems to me that if one
cannot define REST in some manner, then it is impossible to
structure a framework around encouraging it. REST happens.
I have my ideas on how to try to solve this and steer the
users toward a convention, but I would be interested in
hearing some more thoughts on the matter, and in particular
the PUT/POST dilemma.
Eero (rue)
--
Magic is insufficiently advanced technology.
very lucid, thank you.
Many thanks,
Jerry
Not quite. The example given is not rails convention. If you have say this:
/spaces/123/topics/456
then this doesn't make sense, and indeed you have unnecessary coupling.
That's why the suggestion is to have this instead:
/topics/456
However, suppose IDs aren't used, but permalinks instead. Now it is
necessary to specify the spaces namespace in the URI like:
/spaces/123/topics/my-first-topic
This is because it is possible to have a topic named "My First Topic" in
two different spaces. I.e., the uniqueness of the topic permalink is
scoped by space. Rails happens to support these kind of URIs. And I'd
say this fits the REST style.
> The second problem is that it is goofy semantically.
That's because the original example was goofy. Has nothing to do with rails.
> Let's start with the semantics. In Ruby, I might have a class
> representing a User with an attribute called followers. You would
> expect that attribute to be an array of Users, right? The convention
> above is the equivalent of introducing Follower objects instead so
> that you can add and delete them instead of simply adding and deleting
> from the array directly. It isn't wrong, per se, just unnecessary.
In rails you can't actually do this. (well, you can if you try really
hard I suppose, but it's certainly not convention)
> You can kind of see this by asking yourself what exactly is the value
> being PUT at that URL? Is it the same value being returned when I do a
> GET? No, because there isn't really a value there.
>
> You can reduce the coupling by having a URI for the user (say,
> http://blather.com/users/66) and then access the followers resource
> using a link included in the response. Now I have one less thing about
> the interface I need to know in advance (and, which, if it changes,
> will break my client).
That's how rails actually does it. To add/delete followers one PUTs
updates to the /users/66 resource, or alternatively POSTs to
/users/66/followers.
Cheers,
Lawrence
/spaces/123/topics/my-first-topic
This is because it is possible to have a topic named "My First Topic" in
two different spaces. I.e., the uniqueness of the topic permalink is
scoped by space. Rails happens to support these kind of URIs. And I'd
say this fits the REST style.
That's how rails actually does it. To add/delete followers one PUTs
updates to the /users/66 resource, or alternatively POSTs to
/users/66/followers.
Cheers,
Lawrence
Here is what HTTP 1.1 has to say:
> The POST method is used to request that the origin server
> accept the entity enclosed in the request as a new sub-
> ordinate of the resource identified by the Request-URI in
> the Request-Line. POST is designed to allow a uniform
> method to cover the following functions:
>
> - Annotation of existing resources;
>
> - Posting a message to a bulletin board, newsgroup,
> mailing list, or similar group of articles;
>
> - Providing a block of data, such as the result of
> submitting a form, to a data-handling process;
>
> - Extending a database through an append operation.
>
> The actual function performed by the POST method is
> determined by the server and is usually dependent on
> the Request-URI. The posted entity is subordinate to
> that URI in the same way that a file is subordinate to
> a directory containing it, a news article is subordinate
> to a newsgroup to which it is posted, or a record is
> subordinate to a database.
>
> <snip />
The second use-case is exactly the scenario with the Index
and some Article. We may absolutely decree that it applies
only when the subordinate is not (possibly) a resource in
its own right, and PUT should be used instead, but /the spec
does not say that/.
> I don't think there is anything all that radical about REST or HTTP. It just
> seems that way because there was this ill-advised attempt to map CRUD to
> HTTP, compounded by the fact that REST is defined by a dissertation by a guy
> who clearly isn't thrilled with explaining himself to Web developers.
Thing is, if it seems that no-one understands the argument,
the problem might be in the argument, not the audience.
That may apply inversely, too: maybe my argument does not
make any sense, but it seems to me that Roy and the Powers
that Be (awesome band name, by the by) are not adequately
addressing the few relatively minor inconsistencies that are
actively harming the adoption and effective use of a model
that is otherwise very solid.
Here is what HTTP 1.1 has to say [...]
The second use-case is exactly the scenario with the Index
and some Article. We may absolutely decree that it applies
only when the subordinate is not (possibly) a resource in
its own right, and PUT should be used instead, but /the spec
does not say that/.
Thing is, if it seems that no-one understands the argument,
the problem might be in the argument, not the audience.
That may apply inversely, too: maybe my argument does not
make any sense, but it seems to me that Roy and the Powers
that Be (awesome band name, by the by) are not adequately
addressing the few relatively minor inconsistencies that are
actively harming the adoption and effective use of a model
that is otherwise very solid.
(Only, what, a decade later? :)
> And the spec isn't entirely silent, since it does talk about the data being
> POSTed as being subordinate to an existing resource and never refers to it
> in terms of itself being a resource. But I only got clarity on that from the
> blog, not the spec.
Sure, but the examples given in the definition confue the
issue by not distinguishing as "newsgroup articles without
separate representation." Furthermore, it can certainly be
argued that a not-yet-existing blogpost, for example, does
not have a resource identifier yet -- this would be the one
referred to in the response to a POST.
> Thing is, if it seems that no-one understands the argument,
> > the problem might be in the argument, not the audience.
>
>
> Yes and no. There's no question REST became a buzzword and a lot of things
> were labeled "RESTful" that were not. Couple that with a lack of
> developer-friendly exposition by Fielding (and others, many of whom seem to
> want to be obscure in order to be part of the clique), and it is easy to see
> the confusion. I don't blame the spec, per se, since most specs are written
> by committee and poor on addressing the "big picture."
>
> So I'm not blaming the audience, here. Not at all. I'm just saying there is
> a lot of misinformation out there and that the folks who know what the
> intent of all this was - and you can't deny that it has been mind-bogglingly
> succesful as a distributed computing architecture - haven't been terribly
> helpful.
I blame the spec a bit myself -- and to be clear, by "the
argument" above, I was referring to the "REST architecture"
argument and not e.g. your argumentation.
> Correct. But Fielding does say that on his blog:(Only, what, a decade later? :)
Sure, but the examples given in the definition confue the
issue by not distinguishing as "newsgroup articles without
separate representation." Furthermore, it can certainly be
argued that a not-yet-existing blogpost, for example, does
not have a resource identifier yet -- this would be the one
referred to in the response to a POST.
I blame the spec a bit myself -- and to be clear, by "the
argument" above, I was referring to the "REST architecture"
argument and not e.g. your argumentation.