Strategy Pattern in Microservices

Jairam Gauns
Nerd For Tech
Published in
4 min readApr 5, 2021

--

Nowadays for any major application development project, micro service architecture has become the go to solution.

We can imagine microservices to be a set of lightweight services addressing a unit task as opposed to a monolithic software doing all the task. Such architecture solves various problems, but building a microservice architecture has its own set of challenges.

In this article, we would not discuss how to architect a microservices solution, but within a single microservice how helpful a strategy pattern could be.

Use Case

To understand it, let us go over a simple problem statement:

We will develop a service “GeoLocation” which would return latitude/ longitude for a given address .

Service would have an endpoint that would give me the latitude/longitude for a given address. For getting the latitude/longitude let us assume that the client has requested to make use of Google Map geocoding API.

Steps for this would be pretty straightforward:

  1. Define an endpoint taking the name of the city (/coordinates/for/city/{cityname})
  2. Write a service class that would call the external API with the city name and return us the latitude/longitude result.

So far so good, where we have a service that will give me location details based on Google Map APIs.

Now we decide to make use of this service with multiple clients or say we want to use this service in another application. Till the point the customer/client agree with us to use the Google Map APIs there is no issue, but say some clients want to make use of other geolocation APIs like geo-boundaries, telize, maptiles etc. for the same task. In this case we have to update the code of our service to handle it.

This changed requirement needs a strategy that would decide which service to internally use to get the same response of latitude/longitude but the underlying service or rather the underlying algorithm is different.

Also it makes sense to have a single microservice that performs the task of getting geolocation having an underlying support to different geolocation API providers. So let us see what a strategy pattern is and how it could fit in such a scenario.

Strategy Pattern

As Wiki states “ It’s a behavioral design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.”

This rightly fits our problem statement, where we would be now supporting a set of geolocation services and returning latitude/longitude, but which underlying service to choose would differ based on the runtime instruction provided by the client.

Below UML diagram shows how we would be structuring the solution .The GoogleMapLocationContext would be injected in the rest controller.

Strategy Geo Location

Setup in action

We will use springboot 2.4.4 to demonstrate the solution, where we will have a single endpoint that will take the city and service provider based on which the underlying service would be determined. In the services, we will be printing the log statements and returning dummy data.

Solution

Swagger UI

Advantages

With this approach we get a flexible design where the decision of which underlying service to choose is deferred to runtime, making it modular and can be used as a service in multiple applications.

Making use of Enum instead of String for defining the GeoProviders makes provider selection type safe when the client tries to test it via swagger. Also we can now make use of EnumMap which is better performant than a HashMap in our case, where we are creating the context for different strategies.

This approach also makes the code cleaner and maintainable. Instead of a Strategy pattern we could have used conditional checks(if, switch case) in a single service but this would clutter everything inside a service making it a bit difficult to maintain. Also for a new person looking at the code, it would be a bit difficult to understand.

With strategy pattern, extending the code for new geo provider would be easy as we do not have to touch any existing code, instead, we add a new geoprovider type in the Enum we defined and secondly implement the geoprovider service interface for the new provider. That’s it!

The support for new geo location type would be added, thus avoiding the chances of breaking any pre existing code.

Summary

We started with a simple statement of a single service for geolocation, extended it to support multiple geolocation services and saw how Strategy Pattern played an important role in structuring the solution.

We then saw the advantages that we could get with this design as well.

I hope you guys enjoyed reading this article and was fruitful to get a start with designing a strategy.

--

--