How to reuse code between multiple services.

Code reuse is among the fundamental aspects of clean and robust coding. Any developer with a reasonable amount of experience in the game will point out how crucial this is. However, the best probable point to start is by asking ourselves, how can we reuse the code?

Well, some people fight for the "DRY(Don't repeat yourself)" principle and others for the "Share nothing" principle. Most developers are torn between the two. Four principles are used to solve this.

  1. Code replication.

    This involves the actual sharing of the code between different services. That is the code is copied across all the other services. Below is a picture illustrating this:

    Image

    This approach preserves the bounded context. The downside to this approach is if the shared code has a bug, then the bug is transferred across all other services. When a change needs to be implemented then the change has to be copied across all the other services. This creates inconsistencies.

  2. Shared Library.

    This is one of the most common approaches. The shared library is an external artifact.

    Image

    Think of a Jar file, DLL, or an NPM package.

    The main advantage of this approach is that the shared library gets bound to the service at compile time.

    The main challenge to this is Dependency management and change control. Depending on the scope of the Library, one has to juggle between them.

  3. Shared Service.

    This approach focuses on extracting common functionality into a shared service.

    Image

    This approach is common when trying to avoid code reuse. Some of the trade-offs are:

    • Change risks.

    • Performance.

    • Scalability.

As noticed, the majority of this occurs due to movement from compile-time integration to runtime integration.

  1. Sidecar.

    Each application is generically categorized into Operational and domain functionalities.

    Domain functionalities should be focused on loose coupling. However, operational functions like logging, monitoring, and authentication do much better with high coupling and standardization. With this pattern, Operational logic can be shared with every service using an infra piece like Kubernetes, or a Service mesh. Below is what it looks like:

    Image

    Ultimately, the choice depends on you as a developer and the long-term goals of the code that you are writing.

    Thank you and see you in the next.

    Special shoutout to @progressivecod on Twitter.