Search code examples
design-patternsmicroservices

How should multiple microservices interact with shared data?


I'm new to microservices but one thing I understand (at least as a principle) is that each microservice should be independent.

Interactions between microservices should only happen through well defined interfaces, preferably APIs and not a shared database.

Let's say I have a simple web app which displays some content to public users. Internal users (admins) access an internal web interface and write stuff into a database table. If they "approve", the whole content of the table can be made public.

Now, without microservices I could do a lot of stuff.

For example, I could have both services point to the same table and add a "public" flag.

Or I could set up two tables, one "public" and one "private", and ensure that the approval process copies the private table into the public one.

But all these solutions imply that both services access the same database or, at least, that they interact via SQL queries and not REST APIs.

I would be tempted to bundle everything in a single microservice.

But it doesn't feel right: the public service may have different requirements in terms of scalability and so on. And if the "internal" website stops working it shouldn't necessarily disrupt the existing public app. So why couple those components?

This example may be too specific but I suspect the underlying issue is applicable to many use cases.


Solution

  • Solution with a single service

    Implement a service that manages data. The data have a field boolean public. Only users with a given role can invoke the endpoints that create/update/delete data. The endpoint for querying data is open to anyone, but only the user with the given role can see the data that are not public. Achieve this by simply adding AND public=true if the user has not the role.

    Solution with two services and messaging

    Implement a private service that manages data. The data have a field boolean public. Only users with a given role can invoke the service in order to query/create/update/delete data. Every time a data is modified, the service emits a message.

    Implement a public service that consumes messages emitted by the private service in order to write into its database all the data that are flagged as public. If a public data can become private again, do not forget to implement that case too. This public service has only endpoints to query data, open to everyone.