Question

I am thinking of splitting a service serving multiple endpoints into microservices that can serve a set of endpoints but the problem is that the two services have certain logic in common. can the two services use libraries to address this? is it even a good idea to split it up?

to give a hypothetical analogy, lets say the given service has two endpoints,

  1. GET /animals, which returns a list,

    ["dog", "cat"]
    
  2. POST /walk, that accepts the animal

    // request body
    {
        animal: "dog"
    }
    
    // handler
    handle(request, response) {
        animalFood{{"dog": biscuits}, {"cat" : milk}}
        goForAWalk({ 
                       animal: request.Animal,
                       food: animalFood[request.Animal]
                  })
    }
    

Is it a good idea to split the two API's and keep the processing logic in libraries? Feels like the services are still coupled and belong to the same domain?

Was it helpful?

Solution

One of the driving ideas behind microservices, is to have independently deployable components: if team A makes a change on microservice a, they should be able to deploy it whenever they want, and team B should be able to deploy their change on service b at their own pace.

Sharing a common library is on one side a good thing, because you reuse proven code. On the other side, it might create a hidden coupling that may hamper independence if for example one of the team needs the common library to evolve:

  • If the common library is about basic technical services needed for the APIs, change will probably be relatively well controlled: components using the old and the new release should most often be able to coexist, if it's related to the implementation of interoperable standards.
  • If the common library is about domain objects, there are high risk of a more significant coupling, unless great care is taken to ensure backward compatibility. And this might create some technical liabilities over the time.

Therefore, you should assess carefully your design before deciding to split your microservices. Each microservice should be in principle as self-contained as possible. Very closely related features should therefore best stay together. Some strategies facilitate the cohesion: decompose by business capability, by subdomain, or by responsible team.

Ultimately it's up to you to see if it makes sense in your real life context. But for your simplfied example of animal care, I would honestly hesitate to separate the services as some kind of care (go for a walk, feed, ...) seems highly co-related to the relevant animal).

OTHER TIPS

I am not sure it solves anything in your particular case, but it can be done.

An example:

Let's say you are using C#, with Entity Framework Core for database access. In this case all your microservices (the ones made in C# at least) will use Entity Framework Core. In other words, they are all sharing the same library.

"But this is not a library I build myself" you might say. Well, no. But is it really any different? You can build your own general purpose libraries (which might be somewhat less general that i.e. EF Core) and use them like you would with any other library. If you are using Visual Studio, you can even make your own NuGet package and NuGet server.

In fact, many of the most popular general purpose libraries started out as a library solving a specific problem for someone. Try to find some YouTube videos of Jimmy Bogard talking about AutoMapper for instance.

So to summarize, you are not breaking the microservice pattern, by using the same library in multiple services. But you always need to ask yourself, what you gain by splitting a service. And perhaps start by "splitting it internally", so to speak. That is, to prepare the code for a split, but don't actually do so.

Licensed under: CC-BY-SA with attribution
scroll top