“The more complex a solution is. the more difficult it will be to develop it.”
This sounds like a perfectly logical statement, right?
Microservices architectural approach was created to defuse this logic. As a result of an evolutionary approach that is based on development experience, microservices architectural development is the next step in creating complex and flexible solutions.
It is a modular approach that allows applications to be broken down into smaller pieces that work perfectly both together and independently.
Each service is developed separately, the final solution being, practically, the sum of its allocated services. For providing a logical and disruption-free environment, these independent services are containerized and hosted on a server and communicate with each other using language-agnostic protocols.
The microservices approach has become the first option for both development teams and clients, especially because of easy code updates, fast scalability of each service, and the reduced costs associated with the development and deployment of the application.
For what types of projects is this approach suitable?
Even if microservice architectural development is a great choice for building scalable and robust solutions, this approach is not suitable for any project and any business type.
So, you must rely on this approach only if:
- you want to develop complex solutions (e.g., large monolithic applications, big software, convert complex legacy systems);
- work with dedicated development teams for boosting scalability and speed up the development process;
- your business has the resources and capabilities to manage it: can deploy new services or applications fast, can track down issues when they arise, relies on DevOps practices and culture, has skilled testing teams for keeping things on track (add new dependencies, handle database errors, network latency, caching issues, or service unavailability, etc.), has designed the solution together with bottlenecks and errors scenarios, etc.
Need support for choosing the right developing approach for your projects? Get our experts’ advice!
Microservices vs SOA?
Microservices and APIs
Designed as doorways, APIs allow developers to accomplish access to an application’s data or use an application’s functionality.
Practically, APIs are the communications frameworks that facilitate the interactions between developers and web apps and the way a microservice can be distributed to users.
Microservices rely on private APIs for being functional (APIs being responsible for both the usability and the exposure of a service), these usually sending data by means of HTTP requests. The types of API design styles include REST, SOAP, GraphQL, gRPC, and many use specification formats like OpenAPI, RAML, or AsyncAPI.
Resuming the relation between APIs and microservices, we can say that they are made to work together. Each microservice has a decentralized nature imposing the need for a framework specialized communications.
Microservices architecture challenges
- requires product management capabilities (microservices are rather products than projects);
- being an un-traditional model that relies on decentralized items requires greater attention to management and synchronizations;
- requires automation for scaling the infrastructure for avoiding system failure;
- each microservice must be designed for a specific responsibility, resulting in increased complexity;
- being deployed across multi-cloud environments, microservices architecture can generate an increased risk in terms of security;
- complex testing for microservices-based applications.
…still, why you should rely on the microservices approach for developing your projects
- help companies to be more agile;
- allow developers to build more scalable applications;
- faster development cycles;
- can be developed multiple microservices simultaneously;
- a shorter time spent in development;
- small services – code easier to understand and take over;
- each service can be scaled independently;
- no limitations in choosing languages and frameworks;
- better fault isolation – less impact over the complete solution;
- easy maintenance.
Example of a microservices architecture-based project (developed by our teams)
We developed a modular waste management solution based on the “pay-as-you-throw” concept that integrates:
- a dedicated mobile app for waste collectors.
- a management web cloud app with several modules (CRM, Operations, Financial, etc.).
- a dedicated mobile app for the final client.
Based on MSA (Microservices Architecture), SmartSanitation contains several microservices:
- Presentation – written as well using SOLID principles to be reactive to events using RabbitMq, store its own data in separate databases, communicate with other microservices over HTTP using Consul to get IP and port using DNS, be resilient to failure using Polly, segregate business logic implementing Command pattern using MediatR, expose itself at runtime to Consul.
- CRMService – that contains the following technologies: C#, Asp.Net 5, PostgreSQL, EntityFramework Core as ORM, OpenAPI, Steeltoe as client for Consul, MediatR to segregate the business logic.
- TmService – contains contracts, products, services with management options and stores the flow activities. TmService receives events through RabbitMq to mark products when emitting automated invoices and stores its data in PostgreSQL. TmService contains the following technologies: C#, Asp.Net 5, PostgreSQL, MassTransit for RabbitMq client and implementing pub/sub pattern, EntityFramework Core as ORM, OpenAPI, Steeltoe as a client for Consul, MediatR to segregate the business logic.
- FinancialService – a microservice that tracks all invoices and transactions and allows the creation of an invoice manually or automated. FinancialService communicates with PdfService, CrmService, TmService, and ApiOrchestrator directly through HTTP and sends events to TmService through RabbitMq. It also stores its data in PostgreSQL. FinancialService contains the following technologies: C#, Asp.Net 5, PostgreSQL, MassTransit for RabbitMq client and implementing pub/sub pattern, EntityFramework Core as ORM, OpenAPI, Polly for circuit breaker, Hangfire for scheduled jobs, Refit to make it easier to communicate with other services over HTTP, Steeltoe as a client for Consul, MediatR to segregate the business logic.
- PdfService – an agnostic service that communicates with an FTP server with the possibility to store, read and generate PDFs. PdfService contains the following technologies: C#, Asp.Net 5, IronPdf library to generate Pdfs from .cshtml templates, OpenAPI, Steeltoe as a client for Consul, MediatR to segregate the business logic.
- EmailService – an agnostic microservice that sends emails to specific email accounts using Sendgrid client. EmailService contains the following technologies: C#, Asp.Net 5, OpenAPI, MassTransit for RabbitMq client and implementing pub/sub pattern, SendGrid client, MediatR to segregate the business logic.
- Authentication – the service that creates accounts, generates tokens and keeps the logic for authentication. It also stores its data in PostgreSQL. Contains the following technologies: C#, Asp.Net 5, PostgreSQL, OpenAPI, MediatR to segregate the business logic, MailKit to implement custom smtp logic, Steeltoe as client for Consul, JWT for authorization.
- ApiGateway – a gateway service with the role of exposing microservices endpoints and authorization logic. It is the only service that communicates directly with client apps. ApiGateway contains the following technologies: C#, Asp.Net 5, Ocelot library to implement API Gateway using microservices DNS stored in Consul, JWT for authorization.
- ApiOrchestrator – implements custom business logic by aggregating data for mobile and invoices. ApiOrchestrator contains the following technologies: C#, Asp.Net 5, MediatR to segregate the business logic, OpenAPI, Polly for circuit breaker.
- Common projects (ApiKernel, DataAccessKernel, ErpCommons) – are used to implement DRY (Do not Repeat Yourself) principle, adding more stability to the solution by having a common place to store DTOs (Data Transfer Objects) and generic abstraction of the logic.
Each microservice is written using SOLID principles to be reactive to events using RabbitMq, store its own data in separate databases, communicate with other microservices over HTTP using Consul to get IP and port using DNS, be resilient to failure using Polly, segregate business logic implementing Command pattern using MediatR, and expose itself at runtime to Consul. Detached from these microservices, the solution uses separate processes in the same context, with the responsibility to automate some flows using BackgroundServices and Hangfire.
The entire solution is containerized using Docker, keeping each service image on Docker Hub and deploying everything to the host machine using docker-compose.
Interested in building a microservices-based solution for your company/clients with Roweb’s teams?