Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should database primary keys be used to identify entities across microservices?

Given I have two microservices: Service A and Service B.

Service A owns full customer data and Service B requires a small subset of this data (which it gets from Service A through some bulk load say).

Both services store customers in their own database.

If service B then needs to interact with service A say to get additional data (e.g. GET /customers/{id}) it clearly needs a unique identifier that is shared between the two services.

Because the ids are GUIDs I could simply use the PK from Service A when creating the record in Service B. So both PKs match.

However this sounds extremely fragile. One option is to store the 'external Id' (or 'source id') as a separate field in Service B, and use that to interact with Service A. And probably this is a string as one day it may not be a GUID.

Is there a 'best practice' around this?

update

So I've done some more research and found a few related discussions:

Should you expose a primary key in REST API URLs?

Is it a bad practice to expose the database ID to the client in your REST API?

Slugs as Primary Keys

conclusion

I think my idea of trying to keep both Primary Keys for Customer the same across Service A and B was just wrong. This is because:

  1. Clearly PKs are service implementation specific, so they may be totally incompatible e.g. UUID vs auto-incremented INT.
  2. Even if you can guarantee compatibility, although the two entities both happen to be called 'Customer' they are effectively two (potentially very different) concepts and both Service A and Service B both 'own' their own 'Customer' record. What you may want to do though is synchronise some Customer data across those services.

So I now think that either service can expose customer data via its own unique id (in my case the PK GUID) and if one service needs to obtain additional customer data from another service it must store the other service identifier/key and uses that. So essentially back to my 'external id' or 'source id' idea but perhaps more specific as 'service B id'.

like image 398
Mark Chidlow Avatar asked Dec 11 '20 16:12

Mark Chidlow


People also ask

Why microservices should not share database?

Microservices with shared databases can't easily scale. What is more, the database will be a single point of failure. Changes related to the database could impact multiple services. Besides, microservices won't be independent in terms of development and deployment as they connect to and operate on the same database.

Should each microservice have separate database?

Each microservice should have its own database and should contain data relevant to that microservice itself. This will allow you to deploy individual services independently. Individual teams can now own the databases for the corresponding microservice.

How the databases are managed in the microservices?

The Saga pattern In microservices, instead of using traditional distributed transactions (XA/2PC-based), you have to use the sequence of local transactions (aka Saga). Here's how it works: one local transaction updates the database and then triggers the next transaction through messaging.

Can we use same database for multiple microservices?

In the shared-database-per-service pattern, the same database is shared by several microservices. You need to carefully assess the application architecture before adopting this pattern, and make sure that you avoid hot tables (single tables that are shared among multiple microservices).


Video Answer


1 Answers

I think it depends a bit on the data source and your design. But, one thing I would avoid sharing is a Primary key which is a GUID or auto-increment integer to an external service. Those are internal details of your service and not what other services should take a dependency on.

I would rather have an external id which is more understood by other services and perhaps business as a whole. It could be a unique customer number, order number or a policy number as opposed to an id. You can also consider them as a "business id". One thing to also keep in mind is that an external id can also be exposed to an end-user. Hence, it is a ubiquitous way of identifying that "entity" across the entire organization and services irrespective of whether you have an Event-Driven-Design or if your services talk through APIs. I would only expose the DB ids to the infrastructure or repository. Beyond that, it is only a business/ external id.

like image 144
Ankit Vijay Avatar answered Oct 13 '22 09:10

Ankit Vijay