kentoh - Fotolia
Microservices-based approaches solve application deployment problems that have plagued software development for years. Unfortunately, as computer scientist Jerry Weinberg once pointed out, roughly paraphrased: Solving a big problem makes way for many smaller ones.
A microservices architecture expands the number of quasi-independent services in production, and it becomes a real challenge to keep track of those services. Services make request calls to others, and troublesome routing issues emerge as the frequency of those requests increases. Compatibility problems may also emerge when feature releases require changes that are incompatible with prior releases.
To mitigate these threats to application reliability and performance, use tried-and-true microservices architecture design patterns, such as an API gateway pattern to separate outside requests from the internal network and an API composition pattern to put a coordinator between microservices and requestors. Learn the basics of these design patterns -- as well as concepts that include asynchronous web services, API versioning, semantic versioning, and service registry and registration -- to decide which one will resolve the smaller problems microservices adoption created.
Pattern #1: Asynchronous web services
An asynchronous web services microservices architecture does not keep a port open between a request and response. Instead, the network port shuts down and the server takes the request, putting it in a queue of requests and distributing them appropriately one at a time. This architecture design pattern resolves several blocking and timeout issues.
However, it can also increase the complexity of client- and server-side code integrations. These integrations require a particular developer skillset to effectively implement, debug and maintain. To pursue the asynchronous web services pattern, work with the development team on skills development as necessary.
Pattern #2: API gateway
An API gateway is a single API endpoint for the outside world to access microservices. External requests go through authentication once and in one place. The single request in this process can happen over a lower-performance network, like the internet, while the internal call can occur on a higher-performance network, set up inside a data center.
Developers can vary this microservices architecture design pattern in the case of multiple clients -- such as web, native mobile and pure data interchange -- with a gateway for each client. This approach is sometimes known as the backends for frontends pattern. When the gateway calls multiple services and builds a response, that's called API composition.
Pattern #3: API composition
In an API composition pattern, the composer calls several services and builds an appropriate response. The client then makes a single response, with an answer that contains multiple services. Teams can implement API composition as part of a gateway design patterns, or have the gateway call the composition pattern, or create a composite interface that is not part of a gateway system.
However, API compositions can increase overhead through more services calls and complicate debugging. This pattern does not ensure transactional consistency in the database sense.
Pattern #4: API versioning
If changes to an API just include bug fixes or adding a JSON field, then it might not require a change on the client side of the architecture.
Teams also can remove or replace problematic services entirely. In the case of a government-unique ID and or an insurance company-generated unique ID, for example, laws or regulations may prevent breaking down this information by specific, identifiable group.
One way to fix this type of microservices challenge is to keep the existing service up, create a new web service as version 2, and continue this process with new versions. Versioning can quickly become unmaintainable, though, so do not implement this pattern without a long-term plan.
Pattern #5: Semantic versioning
The semantic versioning pattern is a method to track both minor and major changes in an API. Clients can request a specific version, and the microservices code uses conditionals to provide backwards compatibility. While it's possible to version in the URL directly -- as in /v3.21 -- or to query parameters -- like ?version=1 -- it is more common to use an accept HTTP header with the version number embedded in it to pass between client and server with the request and response.
Pattern #6: Service registry and registration
Assuming that a single service runs on more than one endpoint, a router or load balancer can direct traffic, but it won't account for downtime and upgrades. A service registry microservices architecture design pattern enables resiliency.
A microservice can register itself with the service registry. If there is a crash or the application or component of the application is taken down for upgrades, the entry is removed. A registration-based architecture pattern enables the service to scale, but increases complexity in operations.
These six patterns to address microservices challenges could become standard and even included as features in API tools. Some backend-as-a-service providers already offer these options, but until more providers follow suit, make your tradeoffs from one deployment problem to potential others carefully.