If we expose entities over APIs and events, a uniform way of dealing with IDs is very helpful.
none
Architectural considerations, experience from earlier projects.
We will use UUID for PKs and for API exposure (option 2).
The problem with DB-generated IDs (option 1) is that you expose a “technical” ID to the outside world. Technical means: It has been generated outside your active control, and it might be subject to change if you decide to migrate to another form of persistence. By exposing it via API, you make it quasi-permanent, since clients can hang on to the URLs. (See also the sources listed above.)
Usage of UUIDs (option 2) is a viable and pragmatic way out of this dilemma. Harrison (2017, see above) makes the point that one needs to be aware of possible performance concerns, and proposes a “double” approach (option 3): an “internal” generated ID, which is performance-efficient for SQL databases, and a UUID for external exposure.
However, experience from earlier projects (see Projektbörse Prox) and considerations about the expected load make this argument seem nectlectable. Therefore, the pure UUID solution seems appropriate.