There are numerous approaches and patterns for microservice architecture. What I'd like to do here is document a few of the more popular loosely coupled architectures and how to combine them into a single more flexible implementation.
To get a better idea of how this works lets first review a few of the more popular MicroService patterns many developers use and how they can be implemented.
The proxy pattern provides a single url endpoint along with basic authentication and authorization across multiple end points. This pattern gives the Frontend or client developers a single URL and endpoint to manage for all data requests. It can also be extended to provide pass-through authentication via a token auth process like JWT that provides basic authentication to each Microservice.
An extension to the proxy pattern is the aggregation design pattern. This common pattern usually uses a tool like GraphQL at it’s center and allows you to aggregate all or parts of your end point data in one gateway service as a data query tool. This allows for decoupled services while still providing a single URL through a gateway for each service. It’s also provides Frontend developers with one endpoint to query each of the Microservice endpoints as well as perform basic linking or aggregating of the data. In our case we provide a data grid tool that uses Swagger docs to create a simple REST API data mesh for all the related endpoints and allows the developers to pre-configure the desired join queries and cache levels.
The Asynchronous design pattern can be used with a gateway or not, but each Microservice can publish data to a messaging queue like RabbitMQ and subscribe to the data it needs from other services. This requires a bit more upfront configuration for each service but provides the needed data and only the needed data to each end point and can help to reduce query time compared to an aggregation service.
A Microservice Flex Service plattern (a term we came up with at Humanitec after building it into our Walhall platform) allows the developers of each service to choose how they want to share data, either via a messaging Queue or Gateway and API data aggregation, or a fully decoupled backend for frontend pattern. An example is our BiFrost service that provides a simple way to use “workflows” as unique identifiers via UUID’s that are generated in BiFrost models and that can be registered with the core service and each related service entry, then used as a lookup table/service between entries in each backend service endpoint.
The Flex pattern does not require the developer to subscribe to a particular pattern upfront because all the needed services are running in the BiFrost core. This way depending on the use case, type and shape of the data coming into a service developers can choose how to implement each microservice in the optimal way for that service. The only requirement is that each service provides an OpenAPI swagger doc for each service. This helps ensure a standard style and practice for each API service, but also allows us to aggregate the service where needed into the gateway and data mesh.
These services also allow a developer to create lookup service as join tables for data across Microservices where needed and apply flexible centralized role based permissions for them as well. It gives you the developer a lot of flexibility to design an application the way you want, decouple and part out the work where you want and focus on the building of innovative and flexible applications.
Originally published at humanitec.com.