0

Is it an anti-pattern to extract common configuration code as a library and reuse it across microservices?

I am breaking down a monolith app into a few of microservices. What I stumbled upon is: since it is a monolith there's already one single point of e.g. security configuration (enforcing authentication on all endpoint's, defining app-wide roles etc.). And I can see that this part would be copy-pasted everywhere.

Is it safe to extract it as a library, publish to private package repo and make each microservice dependant on it?

3 Answers 3

3

This is still a good idea in my view.

The point of running microservices is not to keep their code-bases unrelated - on the contrary, reuse remains a good and valuable thing.

Rather, the point is that running one service doesn't affect the other: they can be restarted, updated, debugged, duplicated etc. independently of each other. Neither the goal of independence nor the goal of simplicity is any argument against code reuse if there are still some shared goals between services.

3

No...... but its not exactly "safe" either.

The risk you are running here is that your shared library is not generic enough. It isn't a complete solution to whatever it does that will never require changing, it just code sharing what happens to be duplicate boiler plate across your projects.

For example if I add say NewtonSofts Json.net library to my project its a complete solution to json parsing. I'll never be thinking "oh no I need to add a feature to the library to handle this edge case" or "this library does X in a weird way I want to change" because its mature code with a limited and well defined scope.

If however, I look at duplicate code across my various projects, those individual bits of code are not designed to cover all situations. If I wanted to change something in a project the assumption is that I just change or expand that bit of code.

Now if I start packaging them all up into shared libraries I can no longer easily make those changes.

I'm bound to find that some projects require small changes to the default, say an extra function or alternative implementation of an existing function.

If I change the shared library then I have to consider and retest all the projects that use that library! It's impossible to work out the effect of even small bug fixes.

The choice to move this code to a shared library will reduce the velocity of work on all projects and prevents them from making improvements above "the standard"

If I am forced to make change to the shared lib I end up having to program in a risk adverse fashion. Adding new duplicate functions, limiting refactoring etc. I end up with a large and messy "helper library" rather than a helpful library.

Making a good library that works in a generic way and is a complete solution to a well defined scope is much harder than writing a small bit of code that solves a single use case in an individual project. Even if that bit of code is duplicated its often not a good idea to move into into a shared library

2

Is it an anti-pattern to extract common configuration code as a library and reuse it across microservices?

Not inherently. It's perfectly fine to make things that are reused reusable, which is effectively what you are doing. However...

And I can see that this part would be copy-pasted everywhere.

This by itself it not sufficient justification for making this reusable. The important thing to consider here is that not everything that looks similar IS the same.

Taking the example of a video rental store application, just because both Customer and Video have a string Name property, does not mean that you should therefore define that Name property in a common ancestor (interface, base class, composed subclass, value object, ...).

The only real reason to make things reusable is to facilitate the ability to write abstract code which can handle all of the implementations of that reusable structure, e.g. for my video rental store application, if I needed some code that would handle any object with a name the same way. That is not always the case.

I am breaking down a monolith app into a few of microservices. [..] since it is a monolith there's already one single point of e.g. security configuration (enforcing authentication on all endpoint's, defining app-wide roles etc.)

Pedantically, it was a monolith. You're quite clearly removing its monolithic nature by breaking it into microservices. You should build your design decisions based on the future (microservice architecture), not the past (monolith).

So, the question becomes whether these microservices are allowed to eventually break the mold and use individually unique security configurations if they so choose. There is a huge difference between:

  1. Every microservice must adhere to this company-wide security policy
  2. For now, we will have the new microservices implement the current security configuration that the monolith implemented.

The second bullet point leaves it open for individual microservices to later change their own configuration if they have reason to do so. The first bullet point explicitly prohibits it.

This is why I pointed out that not all similarity inherently leads to reusability. This advice very much applies here.

  1. In this case, since you are enforcing the shared use of the security policy, it is perfectly fine (and even recommended) to provide a shared library which is to be reused among all microservices which will have to conform to the same security policy anyway.
  2. In this case, reusability is not warranted, and therefore it would be a bad approach to require a microservice to share/reuse the security protocol which currently is coincidentally the same as for other microservices, but might diverge in the future.

That being said, if your shared library can be optionally implemented or not, and there is no enforcement, you can still create this shared library and let each microservice decide if and when they rely on it or not.

But the benefits gained from implementing a shared library directly depend on how many dependants there are on this library. If hardly anyone uses it, was it really worth the effort and maintenance upkeep? Maybe yes, maybe no.
That's a cost-benefit analysis that your company is going to have to make, I can't make that for you.


So, to summarize, it's contextual.

  • It is not inherently an anti-pattern.
  • If the similarities are coincidentally the same, and it is possible that a change in one implementation does not lead to a change in the other, it's better to not try and abstract this similarity.
  • If the similarities are due to the known requirement of all microservices always needing to implement the same security protocol (in as much as the shared code defines it to be), then abstraction of that shared protocol is definitely justified to cut down on boilerplating.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.