Search code examples
database-designservicearchitecturemicroservices

Howto handle common data in Microservices


i am trying to figure out an general understanding issue regarding microservice architectures.

So for example if I have three services:

  • order service
  • product service
  • user service

And every of this service data needs to be connected to the user. So which user adds the product, which user ordered something etc.

So I would need to say "hey order service, give me all orders of a specific user". That would mean that in the order service database there would be a column for the "user ID" right? But that would just be a column which is not related to the user data in the user service db right? Is this the way to do it?

So so in case that a user gets deleted, the order service needs to be asked maybe if there is still an order with that users id etx.

So question is, are there columns for the user id which are not connected to the user table at all, so no foreign key etc as that are totally different dbs?

Thanks so much!


Solution

  • The idea of microservices is that you should treat them as separate services, they're just small - "micro". That by design means (logically) separate databases. Practically, you might use the same database (e.g. simpler, saves costs), but you would keep the tables separate - no foreign keys between services. You would also avoid touching tables from multiple microservices in the same DB transaction.

    Note: it would be similar for NoSQL DBs - even if you would use the same DB, keep the data at least logically separate.

    That means there's always "eventual consistency" - an object cannot be deleted in multiple microservices at the same time, there's always a delay.

    Here's one way how to handle such User and Order services:

    1. User X creates an order Y in Order services
    2. Fetching X's orders from Order service will return Y.
    3. User X is deleted from User service. A "User deleted" message is sent out to message broker (who sends it to all microservices who are listening to this type of message)
    4. Fetching X's orders from Order service will still return Y. Optionally, you may validate the user for each call to Order service, but that comes with an extra cost of that extra call between services. I'd trust the session cookie or bearer token in most cases without re-validating it for each call.
    5. Now Order service receives and processes "User deleted" message for User X and deletes all X's orders
    6. Now fetching X's orders will return nothing or "invalid user"

    In this example, Order table would probably have something like "user_id" column which would map to user IDs from User table. But it wouldn't be set up as foreign key even if Order table (from Order microservice) and User table (from User microservice) uses the same DB instance.