How to deal with slugs as identifiers?



so my json api retrieves posts. On the site that implements the api you of course want to use slugs in the urls, for ux and seo purposes. So my question is, how to deal with it concerning the json-api.

I would send a call /posts/the-slug-name and expect a result back. But in the result, the id would be a real id (like a uuid), so do I need to allow the user to also request posts using the uuid /posts/ab234-....? If so, should the self link and relation links use the uuid or the slug?

I would generally prefer to only allow one way of retrieving the post, but I fear when seeing the id, the user might expect she can use it to get a resource, also I am not sure, but this is probably needed, to fulfill the json api specifications, correct?

Thanks for your help.


No, you don’t have to support requesting the post by both slug and id; you only have to support the request at whatever URI you provide in the self link (if any). So, if you want to use the slug in self, that’s fine. Then, for id, you could use either the slug or the uuid—using the uuid probably makes more sense, but, if the slug is immutable and you plan to use server-assgined ids anyway, there’s nothing that prevents you from using it instead.


Ahh, thanks for the answer. The slug will probably be mutable, so I would use the uuid or a normal id as id. Cool.


Actually, could I ass multiple self links? Like:


How would I do it, as I can only 1 self link, correct?


Why do you want multiple “self” links ? Why the client could need it ?
A resource should have a single main address to avoid duplication (and nightmare for users/maintainers).

If you want the user to be able to request the resource with the id or the slug, what about using the filters on the collection (/posts/?filter[id]=1234) or answering a HTTP redirection status with the main URL in the location meta ?


Yes, you can only have one self link (at least for now) and, for the reasons @yves mentioned, it might be better that way.

If you expect the slugs to change, I’d either:

  • Make sure any old slug URIs redirect to the URI with the new slug (probably a 302)
  • Or, just make the URI use the uuid.

Having stable URIs is a virtue, for caching, linking, and many other things.

Also, the URI shown to users in your app frontend doesn’t have to match the URI of the API endpoint, of course. So it might just be best to use the UUIDs as the API URI, and leave the pretty URIs to the front-facing app (which should also set up redirects for any slug changes).


Yes, I agree with you and @yves. I like the ?filter idea, just with the slug instead of the id. Thanks for your help.