I am working in a Haskell project that is composed of multiple microservices. There are certain types that are needed by multiple services at the same time and therefore are defined in separate libraries that are imported by whichever needs them (each type is versioned). But there are things about it that make me uncomfortable and I was wondering which are the best practises regarding that topic. In particular:
- I don't know how to handle instances of shared types. In order to avoid orphans the instances must be defined in the type's module for each of the types. But then there are instances that are not needed by all the microservices that import the package and have to be included regardless, potentially adding redundant dependencies to the microservice. An example would be a datatype T that is shared by a frontend and a backend. It has an instance of Store in order to be stored in a database that is not needed by the frontend, but still makes the frontend depend of the store package.
- In order to avoid the previous issue I could introduce a wrapper every time the type has to "leave" a microservice to represent that type going through the wire. In the previous example I would have a Storable T which would have an instance for Store. This adds quite a lot of overhead to the overall development process though.
- Is it even a good idea to share the types or should each microservice define its own representation of each type, so nothing has to be shared? So for a type T a microservice MA would have a representation A.T and an instance to serialise it in order to send the data to a microservice B which would decode that data into a representation MB.T.
And finally, regarding the logistical side of the matter,
- What's the most convenient way to structure the project? Would a monorepo be a better choice than having separate repos/submodules?
- Maybe related to the previous one, is there any way to find out automatically which microservices should be redeployed when one of the shared libraries is modified because the changes in the library affect a piece of code that is being used by the microservice?