I just listened to a Software Engineering Radio Podcast featuring James Lewis on Microservices, and I have to say I am in agreement with almost everything that he said. I love the term Microservices, especially as a way of describing an implementation SOA (Service Oriented Architecture) rather than a way of replacing it. I am not sure I can use the term to describe my own work, because I am not sure I fall close enough to the consensus the community is building on what Microservices are. But one thing I know for sure, it definitely does not mean a SOA implementation using a Service Bus. Another thing that stuck out to me was his definition including the concept that a microservice should have only one reason to change. Object oriented principles used at the service layer. Of course this poses the same question that we had at the object layer. What is one thing? If I have a taxi and I am moving a customer from one location to another, is driving the car one thing? or is changing gears one thing. For now at least I am going to go with the idea that its driving the car. I might go with the phrase that “they do one useful thing”. An Address service, that stores addresses for my user might be useful, but a User Profile service might be even more useful. The devil as always is in the details and you cant answer which is better without understanding the business domain. Something else that is not optional when designing Microservices.
If you decompose your system into a SOA architecture then at some point you have to connect the services together to leverage those services. There are several options that could be considered, many of them violate the SOA architecture you have in place, but you may choose to put them in place for pragmatic reasons. As an architect I loose these arguments often, compromising the architecture because we have a date to meet, or occasionally because developers don’t believe in SOA, the performance argument always raises its head when talking about composing services, but there are other arguments raised and valid reasons for straying from your architecture. We know an understand the compromises we make, but in the enterprise we seldom get a chance to go back and rectify the issues, it is never in the budget, we change teams, the knowledge is lost. Eventually it becomes accepted that that is how the system was intended to work, but I digress. This post is intended discuss the design for connecting SOA services. The following posts will discus an implementation. Rather than simply prescribing the answer, my intent is to reveal the journey to the implementation. There are lots of choices to make, many of them can be for arbitrary reasons.
If you decompose a system how much data does your service require to be useful and how much of that data will be shared with other services. The ideal would be to share referential keys only but how many services will be useful with no shared data, for this post lets just accept that we need to share some data across at least some services. I still meet a lot of people that believe that Services are an application layer construct only, and that it is OK for Services to share the same database, but in my opinion that is simply wrong. Services need to be autonomous and that means not being interconnected at the data level. To be clear, this not about composing data from two services together, this is about data that needs to be in multiple Services for the Services to be useful. A service is not supposed to be aware of other specific services but even though I seldom hear or see this discussed explicitly, a SOA service must at least be aware that the information it contains may be of use to other services, and therefor it must have some method of publishing the data. Since the Service has know knowledge of what data other services find useful, it should be publishing all of its data (really?). I have already hinted at the pattern I am suggesting which is to use the Publish Subscribe Pattern. All data update events to our service should be either published to some publishing endpoint or should allow some subscriber to subscribe to the event. In addition our publish subscribe mechanism needs to be reliable, if you put an integration mechanism in place very few things destroy the confidence of your users faster than integration that fails, even if its failure rate is extremely low.
At this point you may be wondering why bother with the blog post, just put some enterprise grade middleware in place, or use something like nServiceBus, but my goal is to examine how we should build a modern system based on SOA services that are unaware of each other.
So those are the goals in the next post I will discuss the design before moving on to the implementation.