We all have the same goal. Getting out great software quickly, securely, and error free. Microservices can be a great approach for large teams and codebases to help address this need, but there is not a lot of codification around what exactly Microservices are and why they help solve problems.
This document hopes to adress that in an opinionated, but dogma-free approach with the end result being happier teams, companies, and clients.
More likely than not the biggest problem isn't your technical architecture, or tools. Your technical troubles are symptoms, not a cause. The most significant pain point that makes creating and managing large bodies of software and teams is more often the environment that those teams work in, and that their leadership fosters, rather than any technical need or deficit.
The Microservice Manifesto will also cover many of the technical features of Microservices, but if you miss this point you are ultimately doing a disservice to your teams, your company, and your clients.
The core pillars of the Microservice Manifesto are designed to bring the maximum amount of success and value in the shortest amount of time for organizations wishing to adopt Microservices. They have been designed to work well whether you are an organization that currently has enormous monoliths that are difficult to manage and build on or if you are a greenfield startup.
The pillars build on one another, starting with the core pillar, ownership, and building from there. To get the most out of this guide as you begin implementing your strategy for Microservices I recommend that you set priorities within your organization in this order. Can you go out of order? Yes, but you will likely be putting the cart before the horse.
You may notice that these pillars aren't very technical and do not feature some of the standard terminologies that we associate with microservices such as gateways, circuit breakers, service registration, etc. this is intentional as the most significant hurdles in adopting a microservice architecture for your organization are not technical. The implementation techniques and technical components will be further down.
Ownership is the cornerstone on which Microservices are built. Companies tend to produce software systems that are organized the way the company is held. Generally, in a multi-tier system, this manifests as a business team, a UI team, a service team, and a database team.
The problem with segmenting teams based on output type is that you can have mutually exclusive concerns across groups. A DBAs salary is based on the health and maintenance of the database not the creation of a product. This can create strong impasses in the development/deployment cycle.
Companies tend to take an all or nothing approach to delivery in this type of an environment as well. Either the entire stack is delivered or nothing. This is fundamentally at odds with the very nature of Microservices.
By creating cross-functional teams that have full ownership of their destiny hand-in-hand with the business, it enables the delivery of solutions faster and allows the company to find hurdles and pivot more rapidly as opposed to long, grandiose, planning cycles that ultimately create churn that doesn't get delivered or gets delivered in an inconsistent state.
If you aren't creating ownership in your teams and employees, you are hiring brilliant people for no reason. Hire smart people, then trust them to make intelligent decisions. Everyone has the same goal, great products for your customer that don't break, that the teams don't have to stress about when they go home.
Automation is what enables your teams to be able to deliver quickly and with fewer errors. If you don't have automation trying to break down a monolith or deploy several new greenfield microservices becomes an exercise in madness, and no one wants that.
Automation also enables many of the other pillars to be successful such as testing, isolation, and specificity.
We want to have a small of drifts between production code and new code as possible, with the right automation in place we can go from idea to code to thoroughly-tested delivery in minutes or hours instead of days weeks or months.
Testing is essential, so you might think testing should be the second pillar, but when it comes to testing, we want to automate as much of it as possible. Having automated tests that can run during each deployment ensure that we are delivering quality products and not regressing. The benefit to automating that testing is that we get much better use of people time so that instead of executing tests, quality engineers can be writing tests instead.
As a general rule of thumb, your initial tests should cover our likely use cases, and apparent potential bug areas then let bugs from user feedback drive future tests. The reason is, it is nearly impossible to guess which way someone in the wild far removed from your system will use your endpoint. You can try to imagine 1000 potential use cases and still fail to find the one that breaks in production. It is a better use of time to cover your primary use cases, and then when bugs come in replicate them in automated test put in a patch and deliver via automation, this will ensure you do not regress and get patched out in minutes not hours.
Discoverability is more than just a service locator. Discoverability is what enables your teams, whether business or technical to be able to find manage and utilize existing functionality in the system.
The other use case for discoverability is in data governance. Data governance helps ensure that data is consistent and that the organization has the data it needs to fulfill its core business mission. Without ownership in place, and teams being able to own their services creating discoverability and data governance quickly devolves into no-one wanting to take responsibility for the care and feeding of problematic areas of the system. Then each team build a new abstraction on top of it or duplicating it over and over creating more significant problems that compound over time.
After your services can be found, other services need to be able to connect to them. Within the world of microservices, the preferred methodology for this is to expose your services via HTTP(s) and use standard serialization formats that have excellent support across multiple languages such as JSON.
Internal services that are part of a domain cluster do not necessarily have to abide by this. If a service isn't exposed to any consumer(s) outside of your internal domain cluster, you can use whatever makes the most sense such as queues, pipes, TCP, or other technologies. All services that will be utilized by UI or outside services should follow the Accessibility pillar.
Each service is resonsible for itself, but like being a good member of soiety means being aware of the impact you have on others, so too does your service need to account for the impact it can have on other services.
Responsibility also means being responsible for the care and feeding of the services your team owns. It is you responsibility not only to make services that fullfill the needs of the business; you also need to make sure that the services are fault tolerent, stable, and new releases don't interupt consumers.