Live data from Hacker News

Problems with RESTful APIs (2015)

mmikowski.github.io

221–224 of 224 posts

Re: Problems with RESTful APIs (2015)

#221

Earlier quoted context omitted.

> Not sure what you mean by client-generated. The server-side app generates the id because it has to store and interpret it. Per the description above: "Each non-idempotent operation is tagged with a unique identifier" Since the operation originates on the client, the client has to tag it with the identifier, no? And the server has to store this identifier in a way that associates it with any data affected by that op…

> Or are you saying that the client first has to make a round-trip to the server to generate the ID, and then use that server-provided ID for the actual POST? This is always the case for REST given HATEOAS, ie. you've already made some hypermedia requests to obtain the URL of the endpoint to which you will POST. Unless the resource you're posting to actually is the public entry point of your service, but that would b…

Wait, but what about the request used to obtain the URL of endpoint to which you're posting? Isn't that one then not idempotent (since it would create new URLs every time)?

Generally speaking, what is the flow like? Suppose I allocated myself an endpoint, but then never posted anything to it - what does the endpoint actually contain then, if queried? Do unused ones get "garbage collected" somehow eventually?

Re: Problems with RESTful APIs (2015)

#223

Earlier quoted context omitted.

> Or are you saying that the client first has to make a round-trip to the server to generate the ID, and then use that server-provided ID for the actual POST? This is always the case for REST given HATEOAS, ie. you've already made some hypermedia requests to obtain the URL of the endpoint to which you will POST. Unless the resource you're posting to actually is the public entry point of your service, but that would b…

Wait, but what about the request used to obtain the URL of endpoint to which you're posting? Isn't that one then not idempotent (since it would create new URLs every time)? Generally speaking, what is the flow like? Suppose I allocated myself an endpoint, but then never posted anything to it - what does the endpoint actually contain then, if queried? Do unused ones get "garbage collected" somehow eventually?

> Wait, but what about the request used to obtain the URL of endpoint to which you're posting? Isn't that one then not idempotent (since it would create new URLs every time)?

Not necessarily. The numbers don't have to be stored before they're actually used by clients. For instance, you could return a simple integer, like an object version #, and an HMAC(integer, resource URL) to ensure the client can't tamper with it. You only store data under that integer when the user successfully POSTs to that resource for the first time.

> Generally speaking, what is the flow like? Suppose I allocated myself an endpoint, but then never posted anything to it - what does the endpoint actually contain then, if queried?

There are many possible designs here. I prefer something like this in CRUD-like contexts [1], because it gets me a fully auditable change history, optimistic concurrency control and all the storage needed is fully integrated into the app schema in a sensible way.

Combined with the HMAC described above, you don't need to preemptively allocate any storage for idempotent POSTS and you can use simple integers as your unique identifiers. So a POST against a version number that's not the latest version would simply return the version that followed if their POST was the one that succeeded, or a redirect to the latest version if someone else had updated it.

Hopefully you can imagine various relaxations on this to make other trade offs. For instance, a much simpler approach would be to return GUIDs for each possible POST, and you just store each GUID associated with the object when a POST succeeds. If the object's current GUID is the GUID the user is posting, return the current data with 200 OK, otherwise return a 301 Moved to a URL referencing the latest version and let the client try to apply their updates to that. The storage can be reclaimed after a suitable period of time; say a month if your app is for browser clients

[1] https://higherlogics.blogspot.ca/2015/10/versioning-domain-e...

Re: Problems with RESTful APIs (2015)

#224
post #5

Earlier quoted context omitted.

What you just described is only the bare shell of REST. It would also apply to many types of API that don't follow REST principles. One thing this article gets right is that nobody is really RESTful because nobody knows what it means. There's usually a dollop of RPC in most APIs - and there's nothing wrong with that - but the 'pure vision' of REST is similar to the 'pure vision' of the Semantic Web. It's a dream for…

I'm fine with using ideas that make sense and rejecting the ones that don't. It's still solid advice for API design, and the most successful approach we've come up with. Doing REST to the letter always turns into some kind of modern art installation with lots of hammers looking for nails; this is the technology department, religion is down the corridor. I have full confidence that the authors considered these ideas,…

I've made this argument in a much better form elsewhere but I don't have much time.

To my mind the benefit of REST purism was that it killed SOAP. A similar thing has happened at other stages of tech development (e.g. CSS purism cured us of all those awful excesses).

The purism was a mistake and the details were wrong but it was necessary to get everyone behind a common goal - getting rid of something worse.

Post reply on HN