I also tried to use custom types for IDs, but in my opinion, it has more cons than pros. I have to write custom serializers and model binders for them, explicitly convert them to other types, write separate validators etc... At the end I finished with even more bugs than before.
I found serialization of typesafe IDs trivial in Kotlin with Jackson. We have a single generic supertype that has the correct annotation to tell Jackson to use the `value` field as the serialized value, and defines helpful methods like equals. Each new ID type is defined as a single line of code, simply inheriting from this base ID type and providing the actual underlying type (int, string, uuid).
Validators likewise are a non-issue. Jackson handles that automatically during the underlying type conversion, and Java won't allow you to construct a UUID that is invalid.
I see explicit conversion between types as a pro, not a con. If I'm going to take one ID and try to use it as an ID for a different type of entity, I'd better have a very good reason.
Again, I did this with a specific set of tools, but the functionality I used should be available in pretty much any language and serialization framework.
Comments
I also tried to use custom types for IDs, but in my opinion, it has more cons than pros. I have to write custom serializers and model binders for them, explicitly convert them to other types, write separate validators etc... At the end I finished with even more bugs than before.
I found serialization of typesafe IDs trivial in Kotlin with Jackson. We have a single generic supertype that has the correct annotation to tell Jackson to use the `value` field as the serialized value, and defines helpful methods like equals. Each new ID type is defined as a single line of code, simply inheriting from this base ID type and providing the actual underlying type (int, string, uuid).
Validators likewise are a non-issue. Jackson handles that automatically during the underlying type conversion, and Java won't allow you to construct a UUID that is invalid.
I see explicit conversion between types as a pro, not a con. If I'm going to take one ID and try to use it as an ID for a different type of entity, I'd better have a very good reason.
Again, I did this with a specific set of tools, but the functionality I used should be available in pretty much any language and serialization framework.