2

We are migrating a desktop application into web based Spring Boot micro services application with a client imposed mandate of using their existing MySQL database, so all micro services share a common database.

Since its a SQL database we chose Spring JPA (Hibernate).

During project setup, our architecture team generated entities via Hibernate Tools into a "db-commons" project and also added Spring JPA repositories to this shared library citing reusable code.

Although shared entities sound harmless to me, I vehemently opposed idea of having shared repositories, as -

  1. It violates S of SOLID. A micro service should only see & operate on data it owns.
  2. Developers under pressure would directly user these repositories in other services to modify data owned by other micro services.
  3. It leads to duplicate code and possibly missed validations.
  4. It could lead to concurrency & data issues at scale.

Are my concerns wrong ?

If right, did I miss any possible negative impacts (present/ future) ?

  • The SOLID principles are object-oriented principles (not laws) that apply to classes, and nothing else. – Robert Harvey Dec 18 '18 at 15:44
3

I vehemently opposed

Vehemence just makes others stop listening. At the same time, it's a sign that we are (possibly) limiting our perception of the problem and the solution. That said, don't be dogmatic. Be pragmatic.

Although shared entities sound harmless to me, I opposed the idea of having shared repositories

Sharing repositories could be a good idea, overall at the early stages of the project. If we only have one database and only one relational data model, why not?

  1. It violates S of SOLID. A microservice should only see & operate on data it owns.

    It doesn't violate SOLID in any harmful way (yet). One data source per MS is the ideal. It's MS architecture on its state-of-the-art but, it's not a rule written on stone. It's not like Martin Fowler will appear and eat your soul if you don't do it that way.

    Making decisions upon someone else opinion is a mediocre decision-making. When reading articles on internet, remember we often know nothing (or very little) about the requirements that led authors to do what they did. But the most important is, they barely mention the costs of their decisions.

    We'll segregate data sources when we find a good reason to do it. In MS architectures, most of reasons are strategical and rarely technical. MS architectures have been promoted (mostly) by companies with very big monolithic systems. These companies needed a way to articulate different SDLC so that they could reduce the time-to-market, parallelize SDLC, gain the capacity to deploy new features and take'em off any time, etc.

    Consider also that, maybe, you are not completely aware of the context where the project is being developed. Maybe you are missing the company's envision, its limitations and resources at hand.

    Start little. It's ok to adapt the architecture to your immediate needs and resources. And evolve it as the needs come along.

  2. Developers under pressure would directly user these repositories in other services to modify data owned by other microservices.

    Not necessarily, we can isolate repositories in several libraries. Let's say we pack repositories as shared libraries so that each service will only include those it needs.

    Additionally, we make our services connect to the data source with different profiles, each of which with different grants, roles or constraints. For instance, RDBMS come with access control out-of-the-box. Use it.

  3. It leads to duplicate code and possibly missed validations

    It leads to code-reuse, and that could be good for you all at the early stages of the development. Regarding missing code, we will have to contextualise it. For instance, some validations could make sense in some services and none at all in others.

    Bear in mind that one "model" could be interpreted differently by different services. For instance, for "CustomerService" customers are a name, a surname, two addresses, age, gender, etc. For "ShippingService" customers are a name and 2 addresses. The former might need age validations, the last probably not.

  4. It could lead to concurrency & data issues at scale.

    Or not. Premature optimization is the seed of evil. Don't oversize the system until you get evidence to do it.

    The concurrency could be a problem if few services overload the data source so that the rest of the system suffers the consequences. That's a good argument for we to segregate the data source. As for the race-condition over the data, it also happen in high decoupled MS architectures where it's even harder to solve.

Are my concerns wrong?

You are theoretically right, however, you are not being practical enough. You are not paid to implement state-of-the-art architectures, you are paid to solve problems with whatever you have at hand. The excellence might come later (if it ever comes).

did I miss any possible negative impacts (present/ future)?

Yes, but they only matter if they matter.

Shared libs mean that in order to take advantage of code-reuse, other services must be implemented with the same programming language. That's quite contrary to the MS philosophy1.

Code-reuse also couples SDLCs since changes in the common source code might penalize the delivery strategy, hence the time-to-market.

Summarizing

Be pragmatic and open-minded. Be a critic with anything you read on the internet. Bear always in mind that your project dictates the what, when and how it should be implemented.

Reality vs perception

Reality is all about perception. You can provide the "perception" of having different data sources when there's only one "real". Make it real when there's a real reason to make it.


1 - MS architecture is all about freedom of implementation and resilience

  • Note that I didn't address the answer to find arguments for you (OP) to go with against your tech leaders. I rather focused on giving a wider perspective of the things and how you can achieve some goals without draconian solutions. – Laiv Dec 13 '18 at 16:39
0

First of all your microservices should be operating on their own DBs... now even though that's not the case, it's generally a good idea to architect your application in a way that allows for this, or at least doesn't make it obvious that the db is being shared.

I would strongly suggest keeping repositories as useful to an individual MS as possible, and not allowing the sharing of repos across MSs. This way it remains very clear as to who owns what within the system, and also keeps the idea of a shared database away from any other layer of your applications.

0

This shared library could exist for some time because you are in the middle of a migration, but you need a plan to vanish this library as soon as possible.

Using micro services with a shared library is considered a bad smell in some cases, but understandable if you are trying to break a monolith application in small peaces (services). I think we can consider your desktop application as a monolith application.

Deal with a shared library that contains entities and repositories sounds a bad smell case to me. You will need to deal with a lot of changes on this guys and, probably, you will be sometimes forced to upgrade the version of this shared libraries in all micro services. But as I said, if this situation is temporary until you identify the right services owners of each database and remove this shared library on the future, for me is an acceptable temporary solution.

Remember: generally, the micro services is a good idea when they are very independent. Think if you really need these micro services that you created and if a monolith, before break on micro services, it's not a better choice until you understand what micro services you need.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy