Live data from Hacker News

REST Anti-patterns

marcelo-cure.blogspot.com

101–110 of 133 posts

Re: REST Anti-patterns

#101
post #16

Other commenters are correct that POST /accounts/4402278/close is not right (and also fairly hilariously contradicted in the next section). Account status (open, closed, suspended, whatever else) is a property of the account, in the same way that the account owner's name is a property of the account. If you went to all the trouble to represent each account as its own resource, which I assume responds correctly otherw…

The action is "close". The status may or may not be "closed", but that's not what he's doing. Read a little farther. In the brief example JSON for the accounts, there is no "status" property. In fact, there are four actions available on the account: {"rel": "deposit", href: "/account/4502278/deposit"}, {"rel": "withdraw", href: "/account/4502278/withdraw"}, {"rel": "transfer", href: "/account/4502278/transfer"}, {"re…

[deleted]

Re: REST Anti-patterns

#102
post #43

Earlier quoted context omitted.

Can you give an example here of how you think it should work, please. This is one area of REST with which I have a lot of trouble.

One way to approach it would be to have consider deposits, withdrawals, and transfers as subresources of a specific account. So you could POST to "/account/4502278/deposits" to create a new deposit, which would then live at a URL such as "/account/4502278/deposits/87162". And instead of separate subresources for all of these different transaction, it could just be one "transaction" subresource. In the case of closing…

A less related question: how do you decide between adding something as a property vs. creating a new subresource?

Re: REST Anti-patterns

#103
post #16

Other commenters are correct that POST /accounts/4402278/close is not right (and also fairly hilariously contradicted in the next section). Account status (open, closed, suspended, whatever else) is a property of the account, in the same way that the account owner's name is a property of the account. If you went to all the trouble to represent each account as its own resource, which I assume responds correctly otherw…

> Other commenters are correct that POST /accounts/4402278/close is not right (and also fairly hilariously contradicted in the next section). Of course its right. Read the POST spec. POST is for processing data. Its up to the server to what is processed how. If the POST is for closing a bank account, it is valid. I think, my bank would need verify a lot of things before I can close my account with a single click. So…

Just because a flag can be set with PUT doesn't mean the server has to accept it in all circumstances. Maybe there are preconditions elsewhere that must be met first, or maybe only someone with sufficient access credentials can set the flag. This plays pretty well with PUT.

Again, this is the interface to a complex data model, and I would be wary of using a bank that dumped all of its security and process controls into one endpoint's controller.

Also - closing an account is an inherently idempotent operation, no? It can only be closed once. If I request that a closed account be closed again, it stays closed.

Re: REST Anti-patterns

#104
post #37

Earlier quoted context omitted.

Yeah I'm saying this is wrong :\ This isn't how REST is supposed to work

Ah, and therein lies the classic problem. Nobody is doing REST "right," but I'm yet to see anyone point to a de-facto example. Fielding's dissertation isn't a spec, which pretty much means everyone can come up with their own little slice of how it should be done and then say they're doing it right. The true rule of REST: whoever is blogging/commenting about it at the time is doing REST right, all others are confused…

There is a lot ceremony with "REST". Considering REST is architectural pattern and not even an HTTP-specific one I find it very suspect whenever someone says REST API's must use particular HTTP methods or structure URL's in a specific way.

Conventionally that is true and it certainly reduces friction in your API by adhering to common conventions.

Re: REST Anti-patterns

#105

Earlier quoted context omitted.

> you end up with some horrible URLs just so it's RESTful No, you don't. RESTful applications use URLs as opaque identifiers, and communicate all information via resource representations. Communicating information via resource identifiers is decidedly not-RESTful, so any particular URL structure chosen to communicate specific information in the URL is, ipso facto , not RESTful.

I'll give a specific specific example from my own experience of building an intranet. I had documents that people could print. POST /documents/12345/print To me, while this was not RESTful, it was the most readable way I came up with. When I asked somebody who had more experience with REST than me, he suggested I build the URL like this: POST /users/123/print-jobs url=/documents/12345 Doing this, I would have to add…

Why not

    POST /documents/12345/print-jobs
And you say there's not corresponding GET request, but maybe there should be? Perhaps you'd want to list print jobs, get the status of a particular job, and maybe cancel it?

Re: REST Anti-patterns

#106

Earlier quoted context omitted.

I'll give a specific specific example from my own experience of building an intranet. I had documents that people could print. POST /documents/12345/print To me, while this was not RESTful, it was the most readable way I came up with. When I asked somebody who had more experience with REST than me, he suggested I build the URL like this: POST /users/123/print-jobs url=/documents/12345 Doing this, I would have to add…

Why not POST /documents/12345/print-jobs And you say there's not corresponding GET request, but maybe there should be? Perhaps you'd want to list print jobs, get the status of a particular job, and maybe cancel it?

I guess because it's not how I talk. I say "I'll print this document", not "I'll send this document to the printer".

I don't have a print queue because nobody has ever asked for one or shown the need for one.

Re: REST Anti-patterns

#107
post #102

Earlier quoted context omitted.

One way to approach it would be to have consider deposits, withdrawals, and transfers as subresources of a specific account. So you could POST to "/account/4502278/deposits" to create a new deposit, which would then live at a URL such as "/account/4502278/deposits/87162". And instead of separate subresources for all of these different transaction, it could just be one "transaction" subresource. In the case of closing…

A less related question: how do you decide between adding something as a property vs. creating a new subresource?

Good question, I guess it's pretty much the same as deciding if something is a new field or a new table in a database?

Re: REST Anti-patterns

#109
> looking at the URI the consumer must understand all about the given resource

Just because? No.

> The HTTP methods must be used to give the intent of the action that is happening.

That interpretation (PATCH, DELETE, etc) is not "correct", which is endlessly maddening. It was a possible scheme, just like a waterfall process was a possible development scheme. There is no correctness implied. See: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch..., http://cafe.elharo.com/web/why-rest-failed/, http://www.artima.com/lejava/articles/why_put_and_delete.htm..., http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post

I really get sick of these purity guidelines that have no practical use other than to say "see, it works" which isn't compelling.

Re: REST Anti-patterns

#110

Earlier quoted context omitted.

> you end up with some horrible URLs just so it's RESTful No, you don't. RESTful applications use URLs as opaque identifiers, and communicate all information via resource representations. Communicating information via resource identifiers is decidedly not-RESTful, so any particular URL structure chosen to communicate specific information in the URL is, ipso facto , not RESTful.

I'll give a specific specific example from my own experience of building an intranet. I had documents that people could print. POST /documents/12345/print To me, while this was not RESTful, it was the most readable way I came up with. When I asked somebody who had more experience with REST than me, he suggested I build the URL like this: POST /users/123/print-jobs url=/documents/12345 Doing this, I would have to add…

There are lots of aesthetic preferences like this about URLs, but calling them issues of "RESTful"-ness is just plain wrong. REST not only does not prescribe an approach to structuring URLs, it specifies a role for identifiers (URLs in the usual case of HTTP) which makes their construction irrelevant, and worrying about it contrary to the central concept of REST.

> When I asked somebody who had more experience with REST than me, he suggested I build the URL like this:

> POST /users/123/print-jobs

What was the logic: neither version is more RESTful, even if you ignore the role of URLs in REST and adopt what seems to be the usual definition of RESTful URLs used by people who use any coherent definition: the URL represents some logical hierarchy of resources.

In this case, your original "POST /documents/12345/print" implies a collection of print requests (I'd probably call it "prints" or "print-requests" rather than "print", but that's a minor quibble) pertaining to a particular document, to which a new request is added when the user wants to print the document. Sounds perfectly sensible.

The alternative offered suggests a list of print jobs belonging to a user, which is also sensible. But there is no strong reason to prefer one over the other.

And if you were actually RESTful, it wouldn't matter, because your resource representation for the print job/request would actually include both the URL and the user. (And maybe status and other information.)

Both your original (with no representation) and the alternative (with the user in the URL and the document in the resource representation) aren't RESTful because they have information that logically belongs to the resource in the URL and out-of-band context rather as part of the resource. But that's not a matter of URL construction, its fine for a URL scheme to correspond to information about the resources, as long as the information is actually still part of the resource.

> It seems that consensus on how to do REST breaks down when you have custom verbs.

If you have real custom verbs, then you may need to extend HTTP's set of methods (it wouldn't be the first time that has been necessary -- PATCH isn't a base HTTP/1.1 method.)

But there is a difference between a generic action on resources of the type represented by an HTTP method and an action-in-the-domain, and it sounds in your case "print" is an action in the domain, which is an event which should have a corresponding noun -- and thus a resource representation -- in the model. But while URLs are inherently hierarchical, real relationships in real domains are often webs, and so there's not one true way to map it into a hierarchy.

Post reply on HN