Microservices are all the craze right now and have been for some time. But with the dust settling, the architectural style seems to be taking shape. With that happening the benefits and motivation for using this style might seem very similar to people active in the SOA space.
So let’s have a look at the definition of a Service Oriented Architecture. This isn’t as easy as it sounds though as everybody and their grandmother seems to have a different one. Arguably this is one of the main problems the term SOA faces. It’s been used to describe so many things ( a lot of them bad) that it can leave a bad aftertaste. Instead let’s look at Erl’s SOA Principles of Service Design as they seem to hold up. From the SOA Wikipedia page:
- Standardized service contract: Services adhere to a communications agreement, as defined collectively by one or more service-description documents.
- Service loose coupling: Services maintain a relationship that minimizes dependencies and only requires that they maintain an awareness of each other.
- Service abstraction: Beyond descriptions in the service contract, services hide logic from the outside world.
- Service reusability: Logic is divided into services with the intention of promoting reuse.
- Service autonomy: Services have control over the logic they encapsulate, from a Design-time and a run-time perspective.
- Service statelessness: Services minimize resource consumption by deferring the management of state information when necessary
- Service discoverability: Services are supplemented with communicative meta data by which they can be effectively discovered and interpreted.
- Service composability: Services are effective composition participants, regardless of the size and complexity of the composition.
So, at a conceptual level things appear to be very similar and the some of the most verbal advocates of Microservices seem to agree with this. Martin Fowler refers to Microservices as “service orientation done right” in his Microservices blog and in talks he’s referred to Microservices as a “subset of SOA”. His colleague Sam Newman (the one who wrote ‘Building Microservices‘) refers to Microservices as a “style of SOA, similar to how Scrum is a style of Agile”.
So what does the Microservices flavour of SOA do differently to make it so popular? The difference seems to come from a more focussed approach with better defined guidelines on how to implement services. These guidelines are:
- Strive for autonomy
- Use bounded contexts when defining service boundaries
- Focus on business capabilities
The first guideline is strive for autonomy and autonomy is the magic word with Microservices. A lot of what makes Microservices work comes from autonomy. Low coupling and high cohesion are the key terms used here. Put simply, this means trying to remove as many dependencies as possible. Dependencies exist on multiple levels but for services to become autonomous they should at least be technically independent at runtime. This means a service should be able to run, deploy and scale without impacting other services. Of course there will always be dependencies but ideally they should be functional dependencies. A fulfilment service depends on something like an order services to provide it with input. However, that fulfilment service can run, deploy and scale completely independently of the order service.
Guideline number two revolves around bounded contexts (a term coined in Eric Evans’ book ‘Domain Driven Design’) is a way to break down larger domain models into more manageable contexts. Bounded contexts provide a means to determine the boundaries of your services. It also helps in defining the way services communicate with each other. It does so through the way communication evolves. If you see that services need are becoming ‘chatty’, or they need to share a lot of information it is an indication that the bounded contexts of these services aren’t set properly.
Bounded context can also help with modelling your data and data needs. As an example take the order and fulfilment services from before and put them in a web shop. Let’s add a catalog service that can be used to browse products. All three of these services require product information. But what this product information entails will differ, based on the context. In the catalog product information needs to have a title, a description, a price, a picture etc. When you select a product to add to your order you only need a subset of these properties. You’ll need something like the SKU (aka it’s identifier), the title, the price and the quantity. Note that the price can be different in the order context than it would be in the catalog. Maybe a discount applies changing the price of the product on this item. Then when the order (containing multiple products) goes to fulfilment the relevant product properties change again. Dimensions of the product, where it’s located, it’s weight might be relevant information here. While this example is far from perfect hopefully it gives a sense of how data needs can change given their context and how it can help in determining what is needed to move between these contexts.
Finally the purpose of the last guideline is simple, a service needs to add business value. Focusing your services on business capabilities makes them useful to combine in applications that provide value to your business. This guideline also reaffirms the need for high (of functional) cohesion. Creating services for technical reasons rarely adds (business) value and can lead to technical dependencies which contradict the autonomy guideline. Technical reuse is more of a design time affair and each service is free to handle this in it’s own way.
With that out of the way, how do these guidelines impact the Erl’ SOA Principles of Service Design? These principles aren’t given any particular order for service orientation in general but with micro services this doesn’t appear to be the case. The microservices style has a preference for certain principles. While it’s tempting to put all the principles in a certain order that will probably invoke more discussion than is useful. With that said the microservices style definitely favours the following principles:
- Service autonomy
- Service loose coupling
- Service abstraction
- Service composability,
With the other principles (Standardized service contract, Service reusability, Service discoverability & Service statelessness) taking a backseat. While they still apply their weight is less than the others. For an example reusing logic or data is less important than the autonomy of a service and therefore replicating data is far less of a sin if it adds to the autonomy of the service (even more so given how that data might take a different role given the service’ context).
To close, the perception created by the microservices name should be addressed. The name suggests something about the size of the services. It suggests that service should be very small. But in fact this is not the case and it’s something to be very mindful of. Service granularity is very important and going too small might result in the ‘nanoservices’ anti-pattern. Microservices fit well with other IT trends like Agile, DevOps and Continuous Delivery and one of the reasons is that many feel that a single Agile team should be responsible for a service. This actually helps with defining the size of a service, if a service becomes too big for a single (agile) team, it’s probably too big.
At face value the microservices architectural style might seem like a rebranding for the SOA term. But on closer inspection classifying it as a style of SOA seems more appropriate. It stays true to the principles of Service Design but even puts a stronger emphasises on several of those principles. Be mindful though that a Microservices architecture is no silver bullet and introduces whole new challenges of it’s own. This, however, is something to explore in a different post.