If we take a closer look at our model descriptions, we might see that we could do better in some cases. We can make our ID fields simple strings instead of UUIDs and the language code, which is also defined as a simple string. Let’s get going and clean that up!
Looking at the intermediate model for our API documentation (see the OpenAPI class structure in the tapir library), we realize that modifying such a deeply nested case class structure might result in some really messy code.
We can do better than this. When confronted with big and nested structures, we should pick a tool from our functional programming toolbox which is called optics.
Don’t be scared by the name or all that mathematics; there exist some useful libraries for it. In our case, we will pick Monocle, which provides profunctor optics for Scala. The basic idea of optics is to provide pure functional abstractions for the manipulation of immutable objects. Because of their pure nature, they are composable and that results in code that is more flexible and can more easily be reasoned about.
Outline
Now that we have that cleared, let’s make a plan for what we actually want to do.
Steps to perform
Adjust the URL parameter descriptions of {ID} to mark them as a kind of UUID.
Adjust the ID attribute of our Product model to mark it as a kind of UUID.
Adjust the lang attribute of our Translation model to mark it as an ISO-639-1 language code.