Microservices — also known as the microservice architecture — is an architectural style that structures an application as a collection of loosely coupled services, each of which implement business capabilities. The microservice architecture enables the continuous delivery and deployment of large, complex applications. It also enables an organization to evolve its technology stack, scale and be more resilient with time.
To understand the popularity of microservices, it’s important to understand monolithic applications. A monolithic application is built as one single unit. In a monolithic application, server side logic is bundled together in the form of a monolith, with all the logic for handling requests running in a single process. All updates to this system will entail deploying a new version of the server side application.
While there are, and have been thousands of successful monolithic-based applications in the market, development teams are starting to feel the brunt of such large scale deployment operations. For example, in a monolithic application, any small modification is tied to an entire change cycle, and these cycles are invariably tied to one another. Granular scaling of specific functions and modules is also not possible, as teams have to scale an entire application.
In order to overcome the growing complexity of managing, updating and deploying applications, particularly on the cloud, the adoption of the microservices architecture took off. Each microservice defines a specific business function, and only defines operations that pertain to this function, making them very lightweight and portable. Microservices can be deployed and run in smaller hosts, and don’t have to use the RAM and CPU resources of traditional architecture. These operations can also be developed in different languages depending on the use case, so a message-board service can be built in Ruby, and the service delivering them to different users can be built on Node.
Microservices and APIs
Microservices use an inter‑process communication (IPC) mechanism to interact with each other. These interactions could be:
One to one, where client requests are handled by one service
One to many, where client requests are handled by multiple services
If the IPC mechanism involves a request-response cycle, then the most common means of communication are RESTful, which almost always use HTTP/JSON APIs. APIs used as IPCs between microservices are different from traditional forms. These APIs are more granular. Since APIs exposing microservices expose fine grained data, clients may have to follow a one-to-many form of interactions between services to obtain the required data.
Unit and component tests are a common way of validating the behavior of the service being built. The size of the unit test depends on the kind of application it is, often times being the smallest piece of testable software in an application. If a unit test is difficult to write, it often means your test module should be broken down into more independent pieces and tested individually.
Since APIs are the glue for various microservice units to communicate with internal and external services, common integration tests with a functional, performance, load and security flavor can be implemented to ensure your microservice units are running as smooth as possible. Any test you do on a microservices based architecture should provide coverage for every single piece of the inter-process communication at the finest granularity possible.
By combining unit, integration and component testing, we can get better coverage of all the various modules and domains that make up the microservice, validating if the service correctly implements the required business logic.