In finance, diversification is a strategy by which risk is minimized through spreading your securities across multiple platforms to negate the negative performance of any one platform, and on average, yield higher returns. A similar strategy can be applied in development, to minimize risk and generally improve efficiency of Enterprise Software. This strategy is referred to as Microservices or Service Oriented Architecture (SOA).
The inverse of a Microservices strategy is the infamous monolithic application, which until recent years has been the ‘go-to’ strategy for most types of software development. I was surprised when I recently discovered that many large teams, with large applications, often make use of a monolithic strategy when building software. Granted, monolithic applications may have their place and merits in certain forms of development, but I would like to suggest that perhaps it would be best to restrict this to simple end-user applications.
You certainly would not want to dabble in Microservices for mere bragging rights, as over engineering of solutions can often be incredibly detrimental. However, applying a monolithic strategy to enterprise software, might be setting yourself up for a world of hurt.
No enterprise system is written in stone, and most systems typically undergo some form of evolution over their life span. After integrating with various other SOAs we instantly appreciated the value of building software in this manner, and so began our path to refactoring our monolithic enterprise application into an SOA.
Our system was a typical legacy system; heavily invested with business logic and written in a mix of design patterns ranging from mostly procedural to some OOP/MVC code. We found ourselves in the fortunate position of many of our feature sets needing overhauls and refactors to satisfy our ever scaling needs. So through careful planning we began conceptually separating concerns before starting on development. This article serves as the summary of our experience in breaking apart our monolithic application.
A State Of REST
In an SOA you will have multiple independent deployable services that communicate with one another through an HTTP REST interface. These services will send/receive json through these interfaces. This simplified method provides a standard, easily translatable medium of communication. It is possible to transfer practically any form of data through this type of service, however json is by far the easiest to work with, in comparison to the likes of xml or yaml.
Authentication Is Key
Your first concern with an SOA is authentication, and as such it will likely need to be the first thing that you separate from your monolithic application. This service will serve as the gate keeper that will grant access to any other endpoint in your SOA. There is an abundance of boxed solutions such as Keystone, Oauth and OpenID that can cater for central authentication. I would strongly recommend migrating your identities out to one of these platforms if at all possible.
However this is not always viable, as these platforms might not match your access control structures and various other requirements, especially if you are dealing with a legacy system. If you must create your own identity service, then do so carefully and wisely, adhering to proven standards. Typically this service will accept some form of identification through its REST interface and reply with a token that can be used to communicate with other services in the ecosystem. The supporting services will in turn verify any token it’s given against your identity service in order to respond to the request.
One of the most powerful advantages of the SOA is the fact that you are able to choose platforms and architectures that are best suited for the requirements of the services you currently building, as long as each service is capable of transferring a common data format. You may for instance have a requirement for common log data that you would choose to store in a non-relational database while the rest of your application is not. This would be a support nightmare to maintain in a monolithic application.
Scale and Performance
As previously mentioned, each service will be independently deployed, hopefully on its own infrastructure. This also presents a unique opportunity where each service can be made highly available and you will be able to scale its infrastructure independently. Doing this dramatically increases performance and availability across the entire ecosystem. In all likelihood you will also be querying and managing far smaller data sets as your database will contain only the requirements of that service. Your request will also be spread across the various endpoints as opposed your single application. This aspect in itself, may also increase performance.
Choosing an SOA does introduce a great deal of moving parts to your system. It is however, much easier to support than one would imagine. If correctly executed you could swop out the underlying code of one endpoint with little to no effect of the other (providing that your REST interface remains constant). Bugs and issues can also be dealt with in their own respective domains, we’ve also found that they are easier to track down as you don’t have to search through endless lines of spaghetti code to figure out what’s happening. Do keep in mind though that supportability is also dependent on many other factors, such as testing and monitoring.
There is an inherit risk of latency as a result of using http request between the various services and you may also require additional resources to manage all the various moving parts of your SOA. I have found these side effects to be negligible when taking into account the many advantages of Microservices. In many advanced teams and SOAs, various services are maintained by completely separate teams that may not even have any geographical relation. Monolithic Enterprise Systems pivot your complexity on a single point, and this can lead to incredibly brittle and inefficient systems.
It is my hope that this story proves that it is possible to apply this strategy to any system, irrespective of its condition or the size of the team managing it.