I have a small system written in Go with aprox 10 services, and 3 DB (InfluxDB, Postgres, Blockchain) Each service use InfluxDB (some service read, other write), and postgres ( Readonly).

I see 2 options:

  1. In all my services, I use a client to connect directly to DB

    • Pros:
      • I already have it this way.
      • It is easier to write, and more flexible maybe
    • Cons:
      • All services are coupled to 2 or 3 databases,
      • Testing is being quite difficult
  2. I write a REST API in front of InfluxDB, that manage all queries, and systems just invoke those URLs to execute a query

    • Pros:
      • Unloose all my service from a Influx / Postgres dependency
      • Maybe mocking is going to be easier
      • Refactoring to ElasticSearch is easier
      • Centralized credentials
    • Cons:
      • more work
      • more tedious ?
      • Will it bring me something valuable ?

I am looking for advices to take this decision, or maybe, I am asking myself, Will it bring me something valuable ?

  • One of the core principles of microservices is that each service owns its own data. How is that the case if multiple services are connecting to the same database? – Ant P Jul 22 '19 at 7:49
  • Well, inlux is accessed by several differents services, but I can code an API in front of it, so it is compatible with core principe you mention – Juliatzin del Toro Jul 22 '19 at 7:55
  • You might just be moving the problem up by doing that. You might be better off with multiple separate data stores, for example. It's really hard to say with this broad a question. – Ant P Jul 22 '19 at 7:57
  • In my case, IoT device send data to InfluxDB or Blockchain. If it sends it to blockchain, then blockchain herself will write a ReadOnly copy into Influx for faster access to data. There is several services that will read this data, but they can all be considered as clients – Juliatzin del Toro Jul 22 '19 at 8:11
  • 1
    @JuliatzindelToro It's not just about each microservice only connecting to one database, it's about each microservice having a logically separate data model. If you have two services accessing or maintaining the same data model, you have effectively created coupling between those services. This breaks the microservices pattern, because if one service needs to change the shared data model, it will break the other service(s) that are using it. The only real solution for microservices is to have completely isolated and independent repositories. You may have to re-think your architecture. – Aaron M. Eshbach Jul 23 '19 at 14:06

In Microservice architecture, often the goal of Microservices is to find "seams" and break up the services along those seams.

If you have multiple services "coming together" in a single database, then you're, in essence, breaching the seam.

It appears you're splitting your seam in the wrong way. It's my understanding that any given service can definitely use a db connector service to connect to its responsible DB. That's fine.

But to have multiple services essentially be separate EXCEPT at the DB level might be troublesome.

It violates, for example, the idea of having separate teams working on each service. Which is one goal of the microservices architecture. To keep teams focused on specific functionality.

Also, the shared DB violate the cohesion that Microservices are aiming to create. In essence, you have Adhesion on the DB level.

Then there's a question of how brittle those shared databases are, in terms of entities. Can their structure be preserved if they're serving multiple services?

... and I'm wondering about any logic at the database level that's cutting across the service seams by having service entities interacting with each other in the DB, in a way they shouldn't be.

You could do a single API for the DB, but this presents as a somewhat problematic solution because the monolithic database service ends up breaking cohesion for the consuming services.

The proposed Solutions, as I understand them:

  • On each service build a layer to communicate with the DB
  • On the DB, built an API for the Services to consume

I'm not completely sure which is the best but they both abstract away the core issue: Adhesion at the database level.

My suggestion is identify seams in the DB and start "breaking" them apart and to do that process incrementally over time.

It'll solve the testing issues you're having as well. Increase Service cohesion and increase decoupling as well.

  • 2
    I think what you're suggesting is splitting apart the data stores for the different microservices and colocating the now multiple data stores with their respective microservices. If that's the case, I agree with you, but it could be a bit more explicit. The real benefit of this is that each microservice can optimise its data store to its own ends and you don't really gain this benefit by just sticking a shared API in front of the database (in fact you probably make it worse). – Ant P Jul 23 '19 at 13:24
  • @AntP Precisely! :) – ShinEmperor Jul 24 '19 at 14:29

If the Go application is itself a server, then I see no reason why you need to build an intermediate server to handle the DB interface. At that point you're probably over-designing things. Use the standard client libraries, that is what they are for.

If the Go application is the client (such as a command line tool) that is used 'out in the wild' on computers you don't have control over (such as end user machines), then yes, such an API would be a good idea so that you are not exposing your database to the outside world - along with all the risks associated with doing that.

  • 1
    Ok ! So, after reviewing all my services, I have 1 React client, so, I will need to create an API for him. All the others services are server side, so I will let them like that. The only thing I can see is that I have 2 sources of data doing the same actions, so I should probably make a shared lib with those calls, but maybe not an API – Juliatzin del Toro Jul 23 '19 at 9:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.