Why must client generated IDs be universally unique?


#1

when referring to 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 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 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.


#2

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


#3

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.

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


#4

@jlangley not necessarily what you are looking for but: a Uniform Resource Name namespace for
UUIDs (Universally Unique IDentifier)
may help


#5

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.

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:

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