2

This is a generic design question, but where should the responsibility fall in this situation? Should it be the caller's responsibility to check if a record already exists and then call Update? Or should it be the responsibility of the API to make that decision?

In the first scenario, the problem is that the caller is burdened with the business logic, but in the second scenario, the logic pollutes the API and creates hybrid behavior, violating the separation of concerns principle.

I Stand With Russia
  • 6,254
  • 8
  • 39
  • 67

1 Answers1

0

Implementing a CreateOrUpdate endpoint will be breaking some REST principles, but may be convenient for the application developer. You are thinking in terms for a remote function call rather than in terms of resource-oriented API.

Consider this: the API URL identifies the resource.

If the URL points to a collection (i.e. /customers/) then the Create action (typically mapped to the POST method) certainly makes sense. The Update function might makes sense, if you want allow update to multiple resources at one. The POST should return code 201 and an identifier to a newly created resource (i.e. /customers/1); or if the create failed due to resource already existing it should return code 409; 400 if some other constraints like data validation are not met.

If the URL points to an existing resource (i.e. /customers/id/1) then Create action does not make sense and should result in code 400. The update is typically mapped to the PUT method (or sometiemes PATCH, if partial resource update) and generally would return 200 if the update was successful or 4xx series if not.

If you choose to create a /CreateOrUpdate endpoint, which takes POST requests you will have to design your own protocol around it because its behavior and return values will be different depending on circumstance.

@Evert the PUT can be used for create but only when you require client to formulate the endpoint URI with the identifier i.e.

PUT /users/myusername

Problems with that are:

  1. the client must discover an available one,
  2. if a natural identifier is used, there may also exist a natural reason for changing it, which depending on the implementation may be problematic

The main point I am making is to avoid creating REST API endpoints, which represent an action (function). Instead use HTTP methods to effect respective actions on persisted resources.

Victor Olex
  • 1,458
  • 1
  • 13
  • 28
  • Why does this REST answer apply to a "generic design question"? – weston Aug 23 '17 at 00:17
  • 3
    I disagree that create or update is against REST. https://stackoverflow.com/questions/630453/put-vs-post-in-rest that is exactly what PUT is for. – weston Aug 23 '17 at 00:19
  • `PUT` is the correct http verb also for _creating_ new resources. The only reason folks use `POST` for this instead, is because they don't want clients to determine the resource uri, and let the server determine it instead. If you have a natural key that fits in a URI, always prefer `PUT` over `POST` for creation. So this answer is dead wrong. – Evert Aug 24 '17 at 13:57