# Create or Replace

**URL:** https://discuss.jsonapi.org/t/create-or-replace/1627
**Category:** Uncategorized
**Created:** [July 9, 2019, 9:58pm UTC](https://discuss.jsonapi.org/t/create-or-replace/1627 "2019-07-09T21:58:04Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![mattjmorrison](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/mattjmorrison/32/622_2.png) [@mattjmorrison](https://discuss.jsonapi.org/u/mattjmorrison)
#### Post date: [July 9, 2019, 9:58pm UTC](https://discuss.jsonapi.org/t/create-or-replace/1627/1 "2019-07-09T21:58:04Z")

</div>

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.

Thanks!

---

<div class="post-metadata">

### Author: ![ingoogni](https://avatars.discourse-cdn.com/v4/letter/i/df788c/32.png) [@ingoogni](https://discuss.jsonapi.org/u/ingoogni)
#### Post date: [July 11, 2019, 6:26am UTC](https://discuss.jsonapi.org/t/create-or-replace/1627/2 "2019-07-11T06:26:21Z")

</div>

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

---

<div class="post-metadata">

### Author: ![maark](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/maark/32/184_2.png) [@maark](https://discuss.jsonapi.org/u/maark)
#### Post date: [July 24, 2019, 3:21am UTC](https://discuss.jsonapi.org/t/create-or-replace/1627/3 "2019-07-24T03:21:34Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![fiddlerpianist](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/fiddlerpianist/32/821_2.png) [@fiddlerpianist](https://discuss.jsonapi.org/u/fiddlerpianist)
#### Post date: [November 23, 2022, 8:55pm UTC](https://discuss.jsonapi.org/t/create-or-replace/1627/4 "2022-11-23T20:55:52Z")

</div>

Here’s what we ended up doing in my project. We only allowed `PUT`s to happen using a different (i.e., non JSON:API) part of the API, and then we disabled standard `PATCH` updates by explicitly returning 403s when that method is called on the endpoint. This keeps this part of the API compliant with the spec, but we do have to “do our own thing” to support idempotent `PUT`s.

It would be nice if there were a way to have `PUT` (when it _does_ mean full replace) to be addressed in the spec. Idempotency is extremely powerful yet seems to be, in a sense, railroaded into a corner by the spec because some people have, in the past, abused `PUT`s.

---

<div class="post-metadata">

### Author: ![jelhan](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/jelhan/32/822_2.png) [@jelhan](https://discuss.jsonapi.org/u/jelhan)
#### Post date: [December 6, 2022, 9:29pm UTC](https://discuss.jsonapi.org/t/create-or-replace/1627/5 "2022-12-06T21:29:26Z")

</div>

I feel this thread derailed a little bit from the original topic.

If I got @mattjmorrison right, his main requirement as a create or update pattern:

> 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.

The main point seems to be that the client should not need to know if a resource already exists. Not that much if an update is a full-replacement or applies the changes to an existing resource.

This use case has a very specific prerequisite, which is not explicitly called out: It must use client-generated IDs. Only that allows the server to decide if the resource already exists or not.

Typically UUIDs are used as client-generated IDs. Doing so is also recommended by the JSON:API specification:

> 9.1.1 Client-Generated IDs
> 
> A server **MAY** accept a client-generated ID along with a request to create a resource. An ID **MUST** be specified with an `id` key, the value of which **MUST** be a universally unique identifier. The client **SHOULD** use a properly generated and formatted _UUID_ as described in RFC 4122 [[RFC4122](http://tools.ietf.org/html/rfc4122.html)].
> 
> [JSON:API — Latest Specification (v1.1)](https://jsonapi.org/format/#crud-creating-client-ids)

But the use case described by @mattjmorrison has some additional specifics: The client-generated IDs must be stable over time. And two independent clients must generate the same ID for representing the same entity. This is not supported using UUIDs.

The JSON:API specification mentions one exception in which it may be possible to use client-generated IDs, which are _not_ UUIDs: importing data from another source.

> NOTE: In some use-cases, such as importing data from another source, it may be possible to use something other than a UUID that is still guaranteed to be globally unique. Do not use anything other than a UUID unless you are 100% confident that the strategy you are using indeed generates globally unique identifiers.

In my experience this is a rare case. Therefore I’m not confident that it should be supported by the base specification itself. Implementing it as an [extension](https://jsonapi.org/format/#extensions) seems to be the way to go.
