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

2.6k views Asked by At

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'.

3

There are 3 answers

0
Ankit Vijay On BEST ANSWER

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.

0
Mingning Shao On

Well, if you have an idea on Value Object, a business ID will much better for designing.

DDD focus on business, an pure UUID/Auto increment ID can't present it.

Use a business meaning ID(UL ID), like a Customer ID, instead of a simple ID.

0
karansethi On

Suggestion: One can have auto-increment PK int ID which can be used for inter-service mapping/lookup. Advantage of having an autoincrement PK int ID is that it will be easier for database to index it as compared to a uuid/guid.

For exposing an entity identifier, one can have an additional universally unique ID in the table that will be exposed to the client app, hence only exposing what's necessary.

I hope that makes sense.