Support for (standard) UUIDs

Hello,

Internally, in our other services, we use standard UUIDs for all of our objects. This is nice because there are many libraries and tools for storing/validating/dealing with them.

Contentful IDs, on the other hand, are unique identifiers but not in standard UUID form. This means we need to somehow map between Contentful IDs and UUIDs in a deterministic/persistent way. Right now, we are doing this by just storing the map of all Contentful IDs and their corresponding UUIDs. This works, but it means we have to have an additional data store and lookup on top of all of our Contentful API requests, so I am wondering if there is a better way of doing this.

Some things I have tried/considered:

  • Storing the UUID as part of the entry and auto-generating it with a UI extension. This almost works! However, when we receive a delete event via the webhook, it doesn’t include the fields for the deleted entry. That means we don’t have the UUID that our services need to update themselves on entry deletion, and of course we can’t look this up via the Contentful API because the entry is deleted.
  • Converting between Contenful IDs and UUIDs directly. The idea here being to change the Contentful ID string into a valid UUID string by converting it to hex/truncating it etc in some deterministic way that doesn’t require state storage. The problem here is that UUIDs have less bits than the Contentful IDs, so we’d have to truncate them. This is (ostensibly) fine because the collision properties are still ‘good enough’ at this level of truncation, but going from UUID -> Contentful ID is a pain because it requires a partial lookup on the truncated string. This is not possible through the API (?), so we’d have to load every entry and check for a partial match in our own logic, which would be slow for a single lookup.
  • Automatically creating new entries from existing ones that use UUIDs for their Contentful ID. It seems it is actually possible to set the Contentful ID string to a UUID on creation through the API, though not through the UI that editors see. Thus, we can set up a scheduled task on our end that just waits for a while after last auto save and duplicates any non-UUID’d entry into a new one that uses a UUID with all the fields unchanged. The cons of this are that it adds some complexity, because we have to make sure we do the dupe correctly including states, and also it’s pretty terrible UX if you delete the original item while an editor is using it.

If anyone has any better ideas for doing this, I’d appreciate it.

Alternatively, if I could make a feature request either for:

  • Choosing the format of the Contentful object IDs generated. At least for the standard UUID format, which is very popular. Or
  • Allowing fields to be present in delete events sent to a webhook.

Hey Mark,

the IDs that are used for entries are random 128 bit IDs encoded in base 62.
Since UUIDs are also using 128 bit, you could try to just bring them into the UUID format using something like https://github.com/shanehughes3/uuid62 and see if your storage won’t mind that the version and variant aren’t specified correctly.

1 Like

Hi Tim,

I was a little unclear on the expected format of Contentful IDs, so this is helpful. It’s true then that they can ‘fit’ into a standard UUID, even if it means you have to ditch the meta fields. I don’t think that’s a problem for validation; it seems like most libraries/storage allows it (maybe for ‘future’ UUID forms).

Thanks!

Hi Tim,

we have observed that it is not the case for assets. Do you use a different encoding mechanism for those?

Thanks,
Emmanuel

Can I please chase up on this Tim?

Thanks
Emmanuel

Hi Mark and Tim.
I’v solved that case by using https://github.com/shibukawa/uuid62 on out Golang backend.