Identify the Identity (Part III: Resource Identifiers)
Disclaimer: if you are a REST zealot (in particular the enforcement of HATEOAS constraints) you may not like the sentiment of this post.
Part I of this series of object identity had a technical focus on why not to use database keys as object identifiers.
Part II focused on the conceptual theory of why to look for a domain-relevant application identifiers for your objects.
This third part of the series looks at identifiers at a second application boundary – the API.
Get Some REST
With ever-increasing need for automation and integrations between specialised applications, web service APIs (APIs) are the secondary (but very much equal) interface of web applications. It could be argued that RESTful APIs as a design paradigm are now considered the default approach to web service API design. *
One of the core principles of REST is the ability to uniquely identify any resource. Implicit to that is the concept of an Identifier for each resource. But what to use for identifying your resources uniquely?
This brings us nicely back round the conceptual discussion of part II of this series. (If you haven’t read it already, what are you waiting for?) Whether you have a one-to-one mapping between your API resources and your business domain objects or not, the same principal applies; if you can identify a domain-relevant unique identity for your resources, then I think this identifier should be used. It is the same concept, only the interface is different (API as apposed to UI).
At this point you might question “if it’s an API why do I care if it’s domain meaningful or not?”. Actually, I think it’s just as relevant if not more so. While application object identifiers should be meaningful to the end user of your application, resource identifiers much like the path of a RESTful API, should be meaningful to the developer(s) hooking into your API. (Note: this applies equally for users if you are using RESTful URLs for your UI also.) In addition, meaningful URLs apparently help with SEO.
A good RESTful API should accurately represent and convey the domain structure of your resources such that they are understandable to the consumer of the API, self-documenting if you like. Let’s look at this example of an imaginary music catalogue API in an attempt to make this more clear:[GET] /artists/
Using a hierarchical API structure that is recognisable to anyone that has ever bought an album (artist/album/song) means that this API is self-explanatory to the majority of potential consumers of your API. (This in itself will help increase consumer adoption of your API if that is indeed your intention.)
Key to the point here though is the use of domain-meaningful resource identifiers (tom-mcrae, king-of-cards, on-and-on). As a consumer of this API, I not only understand the hierarchical structure of the API, but I’m able to derive the identifiers of other resources (bright-lights as another song on the same album or just-like-blood as another album by the same artist) without querying for them. I like to call these discoverable URLs as I am able to change these identifiers. (This can also be termed Hackable URLs, but I try to avoid the negative and more recent populist connotations of the term “hack”)
Note, embracing discoverable URLs flies in the face of “truly RESTful” services where HATEOAS would [perhaps stubbornly] be applied. I think a cost-benefit analysis of applying HATEOAS is probably for another post.
Suffice to say that I think the pragmatic benefits of hackable URLs outweigh the feeling of superiority gained from rigidly applying HATEOAS constraints.
Of course, like the object identifier discussion of the previous posts, this is all based on the assumption there is a domain-meaningful unique identity for a resource. If there isn’t, you fall back on the arbitrary technical identifier, the UUID.
Part IV of this Identify the Identity series of posts will discuss using UUIDs for APIs in more detail.
* Personally, I think this is due to the fact that REST principles are based on harnessing the fundamental rules of the HTTP protocol, making it a natural fit for web application design and architecture. In my opinion, alternatives such as WCF have been a massive failure due to the fact that they try to abstract the technicalities of HTTP, attempting to falsify the gap caused by application layer boundaries in favour of a more “familiar” local method call approach. In reality, you have to consider your application boundaries, its dangerous to do otherwise. WCF is Microsoft’s API equivalent of Web Forms. This has been shown by their relatively recent push with Web API, akin to ASP.NET MVC being introduced as an alternative to the Web Forms approach to UI design & architecture.