2

I've recently joined a startup that has, in my opinion, a strange (and inefficient) way to access their database.

Their implementation consists of multiple REST APIs that are exposed to multiple clients, these APIs, according to them, were made with a micro-services architecture in mind, that's ok.

My problem is with the way they access their database in those REST APIs, as they made a centralized "micro-service" (lets call it DB service) that receives HTTP requests with a JSON, this JSON is then translated into a database query, executed and then the results are returned as a JSON in the HTTP response, all REST API's use this service to manage their state.

I think this implementation is bad design because:

  1. It is adding unnecessary latency to the database queries, as each query of the other REST APIs must go through the DB Service via HTTP instead of executing them with a database driver or with an ORM library, which would be more scalable and performant.
  2. It doesn't go well with a micro-service architecture as each micro-service must have their own database and not a centralized one.
  3. Database functionalities must be implemented and duplicated manually in the centralized DB service. For example if I need to use some cursors to stream a big chunk of data, the DB service must support pagination via HTTP.

They justified this design by arguing that the service helped them to decouple from the database and if they just wanted to switch from one database provider to another (e.g mongodb to AWS DocumentDB) they just needed to change the DB service. In my opinion if this was really a problem, it was a better approach to make a shared library that used multiple database drivers under.

Here's a simple diagram explaining their current architecture: enter image description here

As they're currently having a lot of performance issues with this design. My suggestions were to remove the DB Service completely, give a database for each micro-service (or use the same cluster with one logical database for each micro-service) and use the database driver (that could be abstracted with a library) in the backend services to connect to the database. Am I wrong? The development time here is not a factor because the project is in a early stage

UPDATE: I just found the real reason they made the DB service, it's because the project wants to be implemented in a serverless architecture with AWS Lambda, since AWS lambda is stateless, a database connection must be opened for each request. As the databases connections are expensive and limited by a fixed number, the DB service provides the ability to just consume one database connection at the cost of a bigger latency and the overhead of a REST API. I still think this could be mitigated by using a database per micro-service.

2
  • 1
    This also introduces another single point of failure, however the central database is also a single point of failure. Regardless of this central DB service, the single database goes against micro services architecture as well. Commented Mar 14, 2022 at 20:04
  • Interesting, as I'm considering similar approach for some similar reasons (replace microservices with serverless) and to reduce the integration costs as every team will instead have a view of a shared model rather than having to write O(N²) translations and synchronisations between the domain models of N microservices. Though I wouldn't use the shared persistence service for the internal state of any stateful services if they needed them. Commented Mar 19, 2022 at 18:34

1 Answer 1

3

No, it doesn't make any sense, you're right.

Being "decoupled" from the DB is a pipe dream. Features matter. A relational database will have to be used completely differently than a document database, a time-series database or a graph database. Unless you really only use the most basic CRUD things, with only a key-value pair or something, you will not be able to migrate to a different DB without "API" changes.

That out of the way, my first move would be to find out the real reasons for this design. Potential real reasons include: "services" need to scale differently, all services developed by the same team, all have the same release cycle, or just somebody read an article about something they half understood and then decided to try.

After you find the real reasons, you're in a much better position to evaluate and to argue for change.

Final note: Usually you'll want "microservices" to be independent. As in: not communicating at all, nor have anything in common. It's because usually they need to scale independently, or have to be developed independently. With different release cycles.

1
  • I just found the real reason they made the DB service, it's because the project wants to be implemented in a serverless architecture with AWS Lambda, because AWS lambda is stateless, a database connection must be opened for each request. As the databases connections are expensive and limited by a fixed number, the DB service provides the ability to just consume one database connection at the cost of a bigger latency and the overhead of a REST API. I still think this could be mitigated by using a database per micro-service.
    – Chromz
    Commented Mar 15, 2022 at 17:50

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.