3 ms·
Nice, but somewhat pointless, since the UUID (or any other type of ID representing an external entity) better be generated by the actor creating that entity, i.
by nivertech 3y ago
Nice, but somewhat pointless, since the UUID (or any other type of ID representing an external entity) better be generated by the actor creating that entity, i.e. the FE client, or in the worst case, the BE/application server. If it is a database server generated ID, it could as well be a serial autoincrement bigint ;)
EDIT:
For those who misunderstood: I'm very much pro-UUID, and against serial autoincrement server-generated IDs. With the exception when you need to heavily optimize for speed and/or index storage space. And even then there are hybrid solutions like using UUID externally, and serial IDs internally.
https://news.ycombinator.com/item?id=39261435 https://news.ycombinator.com/item?id=39261435
- arghwhat 3y agoThere are many reasons for not using a bigserial index, such as avoiding the data leak associated with publicly visible sequential database indexes. These reasons apply regardless of where an index is generated. Generating IDs away from the database is mainly done due to design restrictions demanding it, not because it is beneficial.
- beeboobaa 3y agoTrusting your clients to generate your database IDs... What could go wrong?
- piaste 3y agoWho said anything about trust? Server-side validation still applies; you don't just DELETE /user/{id} without verifying ownership, regardless of where the id comes from. But client-generated IDs make idempotency easier and remove whole classes of errors. They're typically a huge win.
- nivertech 3y ago1. you're not trusting anyone 2. the UUID by itself doesn't authenicate or authorize anything 3. there is a small chance of collision, and it can be handled on the backend/persistance/DB layer, i.e. return error to the client in case of collision and ask to generate a new UUID 4. many non-trivial and/or CQRS/ES apps work like this 5. if you are really paranoid, you can push down UUID generation logic to BFF (Backend-For-Frontend) layer 6. Lots of DistSys problems can be solved with client-generated IDs. But most people mistakenly think that DistSys applies to backend only, and exclude clients from the picture. 7. Scaling RDBMS (especially Postgres) is hard. UUID generation is slower than serial bigint, so it's best to keep it outside DB layer fo this reason also. 8. Client-generated UUIDs help to make client requests idempotent, and enable error handling with retries (although it's better to add an additional layer of request idempotency with IDEMPOTENCY_KEY HTTP header, or GraphQL Relay's clientMutationID).
- iudqnolq 3y agoI think small chance of collision is a misleading way to think about it when any malicious client can submit 100% collisions if it wants to. Dealing with this isn't a big deal, but if you ignore it completely as unlikely/paranoid in a hacked together app you risk letting someone do something like take ownership of an existing record by pretending to create it.
- nivertech 3y agoP_collision = 1 / 2^122 the malicious actor will need to somehow get the authorized session first, then get the real UUID which already inserted into the DB. And now she will be able to do DDoS by replaying create_entity requests with already existing UUID. But ... the same scheme equally applies to server-generated IDs also when used for updates instead of insert/create (even if there is a translation layer between internal and external IDs) ;) In my implementations this create_entity will also have an idempotency key, so after first successful request, the replayed/retried requests will hit the cache only, and skip the database. In case the attacker will also change idempotency_key for each replayed request, then the only remedy is to monitor for this scenarios, or reject requests with the same {sessionID, requestName, enitityUUID} and different idempotencyKey-s over short time intervals. But again, this equally applies to any type of server-generated ID.
- iudqnolq 3y agoSuppose we're talking about an app where users can post events. Each public event has a page at /event/<uuid>. So any malicious user can trivially find the id of an existing event. Suppose there's also an api where you POST a JSON body to /api/v1/event to create an event. This uses a client generated ID so the body contains the title, location, etc and the supposedly newly generated id. A malicious client could submit an existing uuid instead of generating a new one, and the server would need to reject this. I'm not saying this is a big issue, but saying "P_collision = 1 / 2^122" is misleading and gives a false sense of security. P_collision is 100% if a malicious user can specify any id they want and wants to specify a colliding one. I don't understand why you're bringing in idempotency keys. The way to fix this is to reject client generated ids that already exist.
- tsarchitect 3y agowhy not both? Have the table column autogenerate UUID if insert does not have one or else insert if it does. This provides an added flexibility for scenarios mentioned in the comments.
- nivertech 3y agoI do this (i.e. if UUID wasn't supplied in the API call - the backend will generate it), but for me it's only useful for debuging or manual API testing. Reason: I'm not a machine, so I dislike generating UUIDs by myself ;)
- mythhabit 3y agoA serial auto increment bigint is not globally unique. A traditional uuid, is not sequential. This particular uuid are both globally unique and increasing and can be used for primary key. It simplifies certain schemas and architectures.
- kiitos 3y agoClients have/supply meaningful data. An ID isn't meaningful data.
- nivertech 3y agoParents have/supply meaningful data. A name of their newborn child isn’t meaningful data ;)
- kiitos 3y agoIf that name is expected to be a unique identifier, then certainly not!
- nivertech 3y agoFirst name is a locally unique identifier for some period of time (usually a lifetime, otherwise for at least a decade) until a child will change it for any reason (e.g. immigration, conversion to a different religion, gender re-assignment, a recommendation from a personal psychic, or simply not liking it). But yes, it's not a true semantic key since the first name usually doesn't come from an immutable properties of the child, but the last name can be a semantic key, derived from the properties of the family (e.g. geographic origin, profession, hair color, look, etc.)