News for hackers. Stuff that matters.
Re:Problems with RESTful APIs (2015) by int_19h on Wednesday March 01, 2017 @07:55PM (#13770372)
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) by naasking on Thursday March 02, 2017 @09:43AM (#13774261)
> 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...