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.

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
scroll top