Live data from Hacker News

REST Anti-patterns

marcelo-cure.blogspot.com

71–80 of 133 posts

Re: REST Anti-patterns

#71
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…

Your PATCH example makes sense, so I should do something like (depending on your opinions of how to do PATCH requests):

    PATCH /users/123

    [{ "op": "replace", "path": "/accounts/12345/status", "value": "closed" }]
I personally think that's less readable than the original, but I agree that it seems to more closely fit the REST standard.

With the deposit, I don't really understand what's changed here from the original. To me, it just looks like deposit has been pluralised, and everything else is the same:

    POST /account/12345/deposits
 
    amount=10

Re: REST Anti-patterns

#72

This misses the elephant in the room. The REST-inspired API that requires 10,000 API calls to do something that could be done in 1. This is a disaster from a simple performance perspective. There is no simple way to build transactions on top of REST so if you need to do something that involves updating more than one data record you really are best off updating them all in one API call. When you are writing a web fron…

Indeed, I've recently had to use Google Drive API v3 and even though it's version 3 there's still a lot to improve.

Here's what you need to do to copy a file to different folder in C#:

            var newFile = drive.Files.Copy(null, fileId).Execute();
            var newFileInNewLocationreq = drive.Files.Update(null, newFile.Id);
            newFileInNewLocationreq.AddParents = newFolderId;
            newFileInNewLocationreq.RemoveParents = oldFolderId;
            var newFileInNewLocation = newFileInNewLocationreq.Execute();
To be fair it's just 2 API calls but rather verbose. And that's assuming all the calls work

Re: REST Anti-patterns

#74

This misses the elephant in the room. The REST-inspired API that requires 10,000 API calls to do something that could be done in 1. This is a disaster from a simple performance perspective. There is no simple way to build transactions on top of REST so if you need to do something that involves updating more than one data record you really are best off updating them all in one API call. When you are writing a web fron…

> The REST-inspired API that requires 10,000 API calls to do something that could be done in 1.

That's not a REST-inspired API. (It might be an API inspired by the kind of naïve mapping of HTTP verbs onto the base tables of a normalized RDBMS schema suggested to people who don't understand DB design, REST, or application design by certain popular web frameworks default "REST" approach, but that's not REST's fault.)

Re: REST Anti-patterns

#77
post #71

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…

Your PATCH example makes sense, so I should do something like (depending on your opinions of how to do PATCH requests): PATCH /users/123 [{ "op": "replace", "path": "/accounts/12345/status", "value": "closed" }] I personally think that's less readable than the original, but I agree that it seems to more closely fit the REST standard. With the deposit, I don't really understand what's changed here from the original. T…

I would simply PATCH { "status" : "closed" }, as that's how PATCH works in rails.

Regarding the deposits, the difference is that 'deposits' is a collection of deposit resources vs 'deposit' as a verb. I think in this case it makes a lot of sense to do it that way, as you can then GET /account/12345/deposits and see all the deposits ever made.

Re: REST Anti-patterns

#78
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…

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…

> If "close" is an action or activity that acts upon an accounts resource, then his approach makes sense.

Right. Particularly, if a closure request is a thing that has its own status, identity, and associated data elements, which one might wish to examine and interact with (and, while its possible that such interaction might not be possible for external users with privileges only on their own accounts, it might well be possible for internal administrative users), then it makes sense as a resource, rather than a data element buried in representations of another resource.

Without full behavioral requirements and domain model, you really don't know what makes the most sense.

Re: REST Anti-patterns

#79
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…

Reminds me of Agile...

Re: REST Anti-patterns

#80
post #18
post #2

Why is POST /accounts/4402278/close correct in the first example? According to the rest of the post, PUT should be a better option. Closing an account seems to me like its updating a resource, not creating one. Also, will calling that url close the account multiple times? POST is not supposed to be idempotent

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…

What doesn't support PATCH these days? I've been using it for many years with no problems.
Post reply on HN