Create or Replace

I have seen the topic of “PUT” requests discussed a few different places, but never quite exactly in the context that I was looking for. I’ve seen “PUT” discussed in terms of “using PUT for a partial update”. I don’t really care about that, what I am interested in is more a “Create or Replace”.

For example, I have a partner using my API and they want to send some configuration data to my API. That configuration data may change over time in which case I want them to send me the new configuration data. I do not want to put the burden on them to keep track of if they need to use a POST (to create) or a PATCH (to update) that resource. So in my mind this seems like a perfect use case for using a PUT. The alternative would be having them always do a POST - in which case the server would have to do some lookups to find existing configuration to replace it or have them always do a PATCH - in which case I may have to create a “fake” configuration resource if it didn’t already exist.

I’m curious how other people are handling the “CREATE or REPLACE” scenario with jsonapi today without using PUT.


Built into the client, if a HEAD …/{id} returns nothing (404) POST else PATCH.
PUT would be nicer.

Does a configuration belong to something?

Idea #1

Let’s say it belongs to a project. The client could do a POST /configurations and in the document, under the relationships field, make sure the project relationship is defined and points to the appropriate project. Internally, you handle that request by creating a new configuration and assigning it to the project.

Idea #2

Again, a configuration belongs to a project. You could make sure that any new project always has a configuration with default values. Therefore, there is always a configuration. The client needs to simply do a PATCH /projects/abc123/configuration or a PATCH /configurations/def456.

Idea #3

Nothing prevents you from pretending that all configurations (by that I mean all IDs) exist. If the client does a PUT /configurations/abc123 and abc123 does not exist in your database, simply pretend it already exists and “update” it with the appropriate values. You’re building an HTTP API, not a thin layer on top of your database.