Pattern: handling unstable IDs


#1

I have a model whose ID is unstable. Examples of this might be using a username, email address, or blog post title as a primary ID. Most uses of JSON:API I’ve seen use stable, surrogate (or “synthetic”) keys and this is generally a good practice. Sometimes, however, you can’t change the model.

An unstable ID is a problem for JSON:API because if you make an update via PATCH, you might change the one or more fields that cause the ID to change. In that case, the response object will have an ID that doesn’t match what you sent or what’s in the URL.

My proposal for this pattern is that the response includes no data but does have an included:

PATCH /songs/never-gonna-give-you-up
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
  "data": {
    "id": "never-gonna-give-you-up",
    "type": "song",
    "attributes": {
      "title": "Please don't Rick-roll me",
    }
  }
}

200 OK
Content-Type: application/vnd.api+json
{
  included: [{
    "data": {
      "id": "please-dont-rick-roll-me",
      "type": "song",
      "attributes": {
        "title": "Please don't Rick-roll me",
      }
    }
  }]
}

What do people think?


#2

Hi James, I’d like to suggest you create a UUID to refer to this resource outside of the title or some other example. An unstable identifier is likely a resource design flaw, and you should look to address it there.

I believe your proposal is invalid as far as the spec is concerned, and with the backwards compatibility philosophy of the spec it will not be acceptable.


#3

I’d like to suggest you create a UUID to refer to this resource outside of the title

Where, exactly would you suggest I do that? The underlying system has this unstable identifier and nothing I do can change that. The only thing I could think of doing would be to create a proxy system with its own database with UUIDs mapping to the underlying (unstable) IDs, but that seems like an awful lot of work just to be compliant with JSON:API.


#4

I have very little knowledge of your context. However, with my background I disagree with the assertion creating a stable identifier is only for {json:api} compliance.

I am a consultant and I specialize in APIs, modernizing legacy systems, and supplementing existing platform capabilities. One of the absolute first things I do is look at the domain models and architectural context and determine if there is any ‘quick sand’ like this and immediately move to remediate it.

If you can’t be sure of the resources you think you are referencing, are in fact the ones you are, then you have a much larger problem on your hands than {json:api} compliance.