REST Lazy Reference Create GET or POST?
https://softwareengineering.stackexchange.com/questions/326183
-
23-12-2020 - |
Question
I have a REST API where:
GET or POST /foo/{foo_id}/bar?a=1,b=2,c=3
and
GET /bar/{bar_id}
both yield
200 { bar_id: <GUID>, foo_id: <foo_id>, a: 1, b: 2, c:3 }
When no matching bar
is found for the first call, bar
will be generated and persisted. The operation is idempotent, but it is potentially not read-only. Should the first call be a GET
or a POST
? I am leaning towards both, because I can't find a convincing argument for one over the other in everything I have read on the subject.
Solution
GET
should never create a resource. Not one that is visible to the user. It's a read-only operation.
The standard for both POST
and PUT
is to also return a 201 Created
code, instead of 200 OK
, when a resource has been persisted. That is to completely distinguish whether a resource has been saved or simply retrieved.
You should ditch GET
completely. If the first operation will always create a bar
resource and will return a 409 Conflict
when a resource with the same identifier already exists, it's optimal if you used POST
.
However, if you want to create a bar
resource when a new one is passed or simply use an already existing one, you could even use PUT
instead of POST
. PUT
is usually used for both creation and update of a resource, ie. it creates it when none-matching is found or updates it. But remember, PUT
should be only used when you can update an entire resource during one request. For partial updates the PATCH
method is much more suitable.
OTHER TIPS
Should the first call be a GET or a POST?
It should be a GET
.
The key reason is that the client, if I'm following correctly, does not know it is creating a resource nor is setting out to create a resource.
The client wants the current state of the resource from the server. It is not aware this might mean creating a resource and it does not care one jolt that this is the first time anyone has attempted to get this resource before, nor that the server has to create the resource on its end (what ever that means in the context of the server).
The client just wants the current state of that resource.
REST has nothing to do with CRUD operations on the server side. In fact the point of REST is that those details should be hidden from the client. The client doesn't care at all what the server has to do to manage to give the client a representation of the resource. If the server has to run a big SQL query in a transaction to create this resource, client doesn't care.
The thing to remember here is the direction of control. The client is saying to the server give me your representation of resource foobar
. That is what GET is. how the server does that is up to the server.
If you used POST
or PUT
that is the client saying "Here is my representation of foobar
, update yourself"
But in your scenario the client isn't responsible for the initial creation of foobar
, the server is. The client just wants the server's representation and should be unaware of any side effects from that operation.