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:
- Every microservice must adhere to this company-wide security policy
- 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.
- 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.
- 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.