In a microservice based architecture, it is important to keep the different services separated. Entity services is a common pattern now applied to microservices, but entity services is an anti-pattern that works against separation, Michael Nygard claims in one of a short series of blog posts on how to work with microservices.
Nygard, among other things author of Release It!, notes that entity services is a solution to a problem that is commonly rediscovered, and refers both to a microservices architecture e-book from Microsoft and a tutorial from Spring for two of many new examples of usage of this pattern.
For Nygard, an antipattern is a pattern that makes things worse. In arguing that entity services really is an anti-pattern, he uses a large legacy monolithic application as an example. In this application there are multiple instances of the process with all features local and in-process:
Moving this application to a microservice architecture, using an example from the Spring tutorial, some feature will still be contained in one of the services, but Nygard claims that most features will require aggregates consisting of more than one entity, thus creating dependencies between two or more entity services. One example is setting the price on a cart which will involve all services depicted:
For Nygard these dependencies lead to an operational coupling which will affect availability, performance and capacity. He also notices that they create semantic coupling where a change in one service may ripple through to other services. In worst case scenarios this may even result in a service needing to deal with different versions of services.
For Nygard, the resulting context when moving to a microservice architecture with entity services includes:
- Teams can still deploy in their own cadence.
- The semantic coupling requires cross-team negotiation.
- Entity services are invoked in most requests, increasing the load.
- The overall availability is coupled to many services.
By this, Nygard believes the criteria are met for claiming that entity services is an anti-pattern.
In another blog post, Ben Morris, principal architect at Fourth.com, claims that entity services used in a microservices architecture is worse than a monolith and refers to Nygard's post. Morris argues that an important aspect of microservices is autonomy, but the more fine-grained services are the more they become coupled to other services, thus undermining this important autonomy. He notes that changes to a process may be hard as it tends to touch numerous services, and even harder if they are maintained by different development teams. A risk with small coupled services is also that failure in a single service can have a cascading effect, bringing down several processes.
Nygard's post spawned a long discussion. One of the authors from the Microsoft e-book notes that they in the book warn against coupling microservices with HTTP calls. He also notes the importance of having the right domain models to be able to make microservices autonomous.
In an upcoming blog post Nygard will look into alternatives to entity services.