Is it still idiomatic POST if an endpoint both deletes a resource and creates one?

Viewed 71

I've been trying my best to write RESTful API endpoints and recently encountered a scenario I'm not sure how to handle. I have created a model with a time limit for validity and an endpoint that should:

  1. create the resource for the user if one doesn't exist or
  2. delete the old resource and create a new one if it does exist and is expired

My current implementation is an endpoint that handles this logic during resource creation, but something about doing both a deletion and a creation during a POST request feels wrong. Making multiple requests to handle this same task also feels wrong because it seems to introduce the potential for error if the user ends up with two resources or overly verbose communication if there is a request for creation which fails, a request for deletion, and a request creation again. What would be an idiomatic and robust way to approach this?

1 Answers

To first answer the headline question, the deletion part for POST behavior is not idiomatic, because POST is not normally intended for replacement, BUT I do not believe it is strictly forbidden, so depending on your situation (as outlined below), POST or PUT are both acceptable approaches.

When Your Case Should Use PUT:

If you know the ID, then your best bet is to do:

PUT /your/resource/path/<id>

Why: POST is meant more strictly for new resource creation. PUT is used more in situations where you want to "create or replace", which fits your requirement as closely as you're gonna get, in my opinion.

Here is a good source that discusses and supports what I'm saying:

PUT vs. POST in REST

And a good excerpt:

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI."

When Your Case Should Use POST:

If your ID is generated at the back-end and/or you don't know how to identify the resource at creation, then for all relevant purposes you are creating a new resource as far as your usage of REST is concerned, so you should use POST. You may end up with some quirky back-end behavior, which some will argue to death violates REST, but in this case there is no better alternative, other than rethinking your solution at its core.

Final Note:

If you don't know the ID at creation, then you could not even fall back to the DELETE → (re)POST, because to DELETE, you should be targeting by ID. And if you're deleting without an ID, then you have other "is this idiomatic" questions to answer.

Related