# Why must client generated IDs be universally unique?

**URL:** <https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602>\
**Category:** Uncategorized\
**Created:** [July 22, 2016, 9:37pm UTC](https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602 "2016-07-22T21:37:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlangley](https://avatars.discourse-cdn.com/v4/letter/j/9e8a1a/32.png) [@jlangley](https://discuss.jsonapi.org/u/jlangley)\
**Post date:** [July 22, 2016, 9:37pm UTC](https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602/1 "2016-07-22T21:37:51Z")

</div>

when referring to [compound documents](http://jsonapi.org/format/#document-compound-documents) the spec states:

> In a single document, you can think of the type and id as a composite key that uniquely references resource objects in another part of the document

And when referring to [resource identifiers](http://jsonapi.org/format/#document-resource-object-identification) it says:

> Within a given API, each resource object’s type and id pair MUST  
> identify a single, unique resource.

To me this implies that the same `id` can be present multiple times, provided that each time it appears it is associated with a different `type`.

However, elsewhere the [spec](http://jsonapi.org/format/#crud-creating-client-ids) states that a client-generated ID must be **universally** unique. Why does a client have to generate a universally unique `id` yet a server generated `id` only needs to be unique within a single `type`?

The background to this we’d like to upsert, but JSON API doesn’t seem to support that. So it seems we need to attempt to create a resource with a client generated ID, and if we get a `409` we need to attempt an update instead. We have an identifier that is definitely unique within the specific resource type, but we can’t guarantee that it is unique universally across our API.

---

<div class="post-metadata">

**Author:** ![espadrine](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/espadrine/32/303_2.png) [@espadrine](https://discuss.jsonapi.org/u/espadrine)\
**Post date:** [July 23, 2016, 9:36am UTC](https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602/2 "2016-07-23T09:36:31Z")

</div>

> elsewhere the spec states that a client-generated ID must be universally unique.

This only relates to resource creation.

> A server MAY accept a client-generated ID along with a request to create a resource.

That ensures that a future resource with the same type / id combination can be assumed to refer to the same object.

Using an ID that is not universally unique would mean that two clients concurrently creating distinct objects may specify the same id, and only one would be attributed the id it specified. That would be unfortunate for the other.

On the other hand, upserts can be performed through a normal [resource update](http://jsonapi.org/format/#crud-updating), if that update contains all information necessary for the creation of that resource.

Aside, I too would love to know more definitely whether ids are document-wide unique or API-wide unique.

---

<div class="post-metadata">

**Author:** ![jlangley](https://avatars.discourse-cdn.com/v4/letter/j/9e8a1a/32.png) [@jlangley](https://discuss.jsonapi.org/u/jlangley)\
**Post date:** [July 23, 2016, 10:25pm UTC](https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602/3 "2016-07-23T22:25:51Z")

</div>

> [@espadrine](#):
>
> Using an ID that is not universally unique would mean that two clients concurrently creating distinct objects may specify the same id, and only one would be attributed the id it specified.

So I suppose my question boils down to: what does “universally” mean in this context?  
If I create a resource of `type` A with `id` 12345 it’s clear that any subsequent attempt to create a resource of `type` A with `id` 12345 should result in an error (`409`); what’s not clear to me is whether a subsequent attempt to create a resource of `type` B with `id` 12345 should succeed or fail.

> [@espadrine](#):
>
> Aside, I too would love to know more definitely whether ids are document-wide unique or API-wide unique.

The way I read the resource identifiers section `id`s are API wide (within a `type`).

---

<div class="post-metadata">

**Author:** ![A-Helberg](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/a-helberg/32/250_2.png) [@A-Helberg](https://discuss.jsonapi.org/u/A-Helberg)\
**Post date:** [July 28, 2016, 8:52pm UTC](https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602/4 "2016-07-28T20:52:25Z")

</div>

@jlangley not necessarily what you are looking for but: [a Uniform Resource Name namespace for  
UUIDs (Universally Unique IDentifier)](https://www.ietf.org/rfc/rfc4122.txt) may help

---

<div class="post-metadata">

**Author:** ![jlangley](https://avatars.discourse-cdn.com/v4/letter/j/9e8a1a/32.png) [@jlangley](https://discuss.jsonapi.org/u/jlangley)\
**Post date:** [August 2, 2016, 11:27pm UTC](https://discuss.jsonapi.org/t/why-must-client-generated-ids-be-universally-unique/602/5 "2016-08-02T23:27:00Z")

</div>

Sorry, doesn’t help me.

My situation is the client already has data and an associated ID (but not a UUID) supplied by another system. I want to **idempotently** create a resource in my API holding that data and having that identity.

I _could_ have the client pass its ID as an _attribute_, and have the API respond with a `409` (or another `4xx` code) if it receives multiple POSTs with the same attribute. This complies with the spec but feels like reinventing the wheel.

> [@espadrine](#):
>
> On the other hand, upserts can be performed through a normal resource update

You mean just PATCH to `/resources/client-generated-ID` and have the server implement upsert? I suppose the spec doesn’t explicitly _forbid_ this, but it seems a bit of a stretch - that resource update section _does_ include the following:

> [@](#):
>
> A server MUST return 404 Not Found when processing a request to modify  
> a resource that does not exist.

That seems to cover the situation when the server receives the first “upsert” request. (I suppose you could argue that since the HTTP spec allows PATCH to create resources as well as update them, the first request is a “request to create” rather than a “request to modify”, and therefore this restriction does not apply. But I don’t see anything to support such an interpretation when using JSON API.)
