top of page

On Identifier types, type-safety and Guids

Updated: Jun 17, 2018

How many times did you find yourself looking at an API which accepts some sort of string or int-based identifier and not being sure what the identifier should represent? This sort of thing happens a lot when you use several different DAO or Repository objects. For instance, I may have:

Note how easy it would be to accidentally pass a dog id into the get method of CatRepository.

Now, back in the happy days of Ada and Delphi (and Pascal, of course), you could define your own types; for instance, I could write:

for which the compiler will produce an error if I try to pass a DogId instead of a CatId. Another highlight of using specific types for identifiers is that we now provide a higher-level abstraction over the concrete type of the identifier. I no longer care that a DogId happens to be a string – I just treat it as a DogId everywhere in the system.

Scala also has the type keyword, allowing us to define custom types. However, this only defines a type-alias, not a truly separate type in the type system. As a result, I could pass a string instead of DogId or even worse, a CatId instead of DogId:

A few years ago, Eishay Smith mentioned during a conversation that he likes to use Java Generics to enforce identifier type safety. He suggested what in Scala would look like:

Using the Id[T] type, I can now use the T type argument to break compilation when passing wrong identifier values:

A final issue that bugs me is that nowhere in the Java ecosystem is to be found a better Guid implementation than java.util.UUID, which contains some terrible code smells hidden inside it. At Wix, we’ve been using a Guid[T] class for some time now, which looks something like this:

This post was written by Shai Yallin


bottom of page