Live data from Hacker News

REST Anti-patterns

marcelo-cure.blogspot.com

41–50 of 133 posts

Re: REST Anti-patterns

#42
post #28
post #18

Earlier quoted context omitted.

You may be operating under the misapprehension that "POST" means "CREATE". It WOULD make a nice set with CRUD operations: POST - Create GET - Read PUT - Update DELETE - Delete But that's not actually how the HTTP verbs are defined[1]. Instead, my own mental mapping looks something like this: GET - read information. Must be idempotent and side-effect free so this one really IS just for reading. DELETE- delete. Usually…

I like to think of DELETE as "if the response to the DELETE is 200-level then further GETs to the resource should be at the 400-level." Call those responses to GET requests "2XXing" and "4XXing" respectively. Similarly a PUT should make sense whether the underlying resource 4XXes or 2XXes, and should in either case make it 2XX with the same response. Then POST is just a verb which does not share these semantics at al…

That's a nice simple view of it, I really like it.

Re: REST Anti-patterns

#43
post #37

Earlier quoted context omitted.

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…

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

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.

Re: REST Anti-patterns

#44

Earlier quoted context omitted.

There's nothing to stop someone putting resources on an api which do the one thing a client needs to do. And what you describe nothing to do with REST, it's to do with overly fine-grained API design, without taking your users into account.

I have frequently seen it done in the name of REST, and had people argue that an effective API is an evil RPC.

First and foremost an API which services it's clients need well is a good API.

There are many people arguing things that aren't REST (e.g. pretty urls, media type based versioning) in the name of REST, and there are also (fewer) people trying to talk about things that are REST (e.g. HATEOAS) in the name of REST. This makes it (understandably) easy to blame REST due to the large amount of confusion.

In fact, I did a Bad Thing in my other comment by pointing out that REST-as-widely-understood isn't REST as all the mature individuals who are interested in REST APIs have taken to referring to them as Hypermedia APIs in order to avoid having to rehash the differences and kick off a flame war. I wouldn't have done it if OP hadn't mentioned HATEOAS.

Re: REST Anti-patterns

#46
post #35

HATEOAS is much less important for programmatic APIs. You either hard-code knowledge of the URL scheme in the API client, or you hard-code knowledge of the payload schema in the API client. There isn't a huge amount of difference here IMO, especially if you have some kind of versioning mechanism in your URL routing. Hard-coding URL scheme permits more pipelining and concurrency in the client. Embedding URLs in payloa…

The dream is that your client can dynamically update itself or seek out ways to process new, incomprehensible things* that it encounters while traversing a rest request (see "Code-on-demand in REST literature).

If you think this is possible in the wild or not is another matter.

*each nugget of data can be versioned and meaninged independently

Re: REST Anti-patterns

#47
post #5

"Correct POST /accounts/4402278/close" bullshit. POST should not contain all details in URL. POST can have body and each query should not be unique. Stopped reading after that.

The REST design pattern does require that your URLs are structured in this way, and I don't think that's really open to debate. Whether or not all HTTP APIs need need to be RESTful is a different issue.

Re: REST Anti-patterns

#48
post #5

"Correct POST /accounts/4402278/close" bullshit. POST should not contain all details in URL. POST can have body and each query should not be unique. Stopped reading after that.

URLs should... well... locate a resource. The resource is an account.

Only when it's GET request. This request will not return you any resource information, with id if account or without.

Re: REST Anti-patterns

#49
post #34

Earlier quoted context omitted.

This depends on your data model. If "status" is just a property on the accounts resource and doesn't have further meaning, I would tend to agree with you. If "close" is an action or activity that acts upon an accounts resource, then his approach makes sense. Since the context is an account that we "need to close," I would assume the author is talking about something more complex than a database field. It's probably a…

REST is just a representation of the underlying data. What does it matter if "status" is a database field or not? More specifically, it shouldn't have to matter to consumers. Because of the way REST and HTTP work, clients intuitively understand retrieving and modifying resources (via GET, POST, PUT, PATCH and DELETE). But they don't understand interacting with special-purpose endpoints (POST always implies "make a ne…

What if 'status' isn't a column in the account database? What if closed_accounts is a join table or something else? Then wouldn't adding a /close route be hiding idiosyncrasies in your data model, not the other way around?

It seems like we spend a lot of time designing object relations that map a domain, but maybe not so much mapping domain-specific actions.

Or would you consider all of the above bad practice?

Re: REST Anti-patterns

#50
post #15
post #5

"Correct POST /accounts/4402278/close" bullshit. POST should not contain all details in URL. POST can have body and each query should not be unique. Stopped reading after that.

I disagree. In the example, account 4402278 is a resource represented at /accounts/4402278; actions on that resource should be performed … on that resource, not on some other resource (e.g. all accounts, at /accounts). This also gives increased future-proofing, since someday one might have uncloseable accounts; those accounts could still live under /accounts, but would simply have no /close endpoint (as opposed to ha…

"close" is a verb, so it's not a resource, it's a method and 4402278 is just argument of that method.
Post reply on HN