13 Comments

Great post, Raul!

Expand full comment

Thanks, Nina!

Expand full comment

Quality knowledge insigh Raul! Duplication is way much better than wrong abstraction.

Expand full comment

Exactly, Daniel!

Expand full comment

I think Internet is saturated with the repeated concepts like Kafka, mongoDB, gateway, eureka etc etc.

This post is what we as a Engineer look for while designing or while understanding the architecture.

Thanks and kudos!

Keep up the great work!

Expand full comment

I wrote this from the memory of some scars 😉

Thanks for the kudos, Vivek 👊

Expand full comment

Hope, your scars will help us from our future bleeds 🤜

Expand full comment

Great article about an important topic everyone engineer should master. Thanks, Raul!

Expand full comment

Thanks for reading, Rafa!

Expand full comment

I think DRY is sometimes overused. DRY is about duplicated knowledge, not code.

Also, I'm a big fan of LoB (Locality of Behavior) where you keep things as close to its usage. If one util is used only at one microservice, why move it into a shared package?

And I'm having the same experience at my current company with moving all utils in a single package.

Awesome article, Raul!

Expand full comment

Great post Raul!

A lot of the usual ways of doing stuff don't work that well with microservices and this mindset shift is probably the most difficult.

Also, thanks for the mention!

Expand full comment

Not sure I agree with everything.

I've seen mostly infra code in shared libraries. Things like healthchecks, metrics, pub/sub, object storage, outbox.

There was one edge case when we considered making a library - to convert between our data format and format we sent to external consumer. Again, closer to infra than business.

So my points are about infra code in shared libraries.

1) A bug in the shared library doesn’t just affect one service—it spreads across the entire system

1.1 to me it's much worse to have several near-identical implementations in different services. You do need to test, review and support all of those versions

1.2 you can always spin up a separate environment with all the affected services to see if your library works or not (or use one of the test environments for it). time-consuming, yes, but major changes are rare in my experience

2) shared libraries create situations where updating one service requires changes in others

that's what backward compatibility is for. shared library or not, I believe its a good idea to talk with your colleagues and test your changes thoroughly. can you share an example of this?

Expand full comment

Although I agree with there are some circumstances where you can have a Death Star problem, to be honest, shared libraries are the norms and are good things: either they are runtime, serialization, network primitives, containers, algorithms, shared libraries are ubiquitous and one shouldn't try to replace them to avoid a Death Star. Instead, one should ask themselves what makes a library a death star? I would cite a few, all related to the point you made.

- Poor deployment/release strategy. If a service cannot use a specific version without breaking other libraries or services, you're doomed, even without shares libraries.

- bad versioning, which create dependencies hell.

- bad management of backward/forward compatibility. I would say that you cannot have good microservices and continuous delivery if you aren't able to manage both versioning and backward compatibility

- poor encapsulation, especially with leaked interface. Proper interface and encapsulation are the secret to achieve good versioning and backward compatibility

- poor acceptance tests. They aren't necessary but how would you know that you achieve the above without them? Don't wait for your users to tell you!

Expand full comment