orta / relay-redwood-app-example

An example of using Relay in Redwood
MIT License
27 stars 5 forks source link

Question: What's a good way to have Object identification Id without saving the typename to database? #3

Open muhajirdev opened 2 years ago

muhajirdev commented 2 years ago

hey @orta awesome works

I see that in this repo you're saving cuid:typename into database. If a database is already using int autoincrement. This won't work, because we cannot put string to an Int

I know we can base64 id:typename it in each mutation and resolver, before we give the id to prisma. But this would be very verbose. Is there a good way to

One possible way is probably by writng an envelop plugin. I am going to explore envelop.dev. Just curious if you have any opinion about this problem

Another thing I am thinking is that maybe ID scalar can do serialiaze and deserialize. in serialize we can encode it and in deserialize we can decode it. But not sure where I can read more about this

orta commented 2 years ago

You probably want to use a different field than id for your global UUIDs - it could be as simple as uid which is just ${id}:[model-type] - see nodeInterfaceIdField in the compiler settings: https://github.com/facebook/relay/tree/main/packages/relay-compiler#configuration

muhajirdev commented 2 years ago

Interesting approach, thanks for the insight.

Actually, what’s the standard practice for graphql object identification. Do people usually put the node id inside database model, alongside the real primary key?

Or the node is usually computed on every request via base64(typename:id)? I saw pothos graphql doing this

I’ve been googling around since last week, did not find a good resource.

How do you guys do it at artsy?

orta commented 2 years ago

An my app today, the node id is the primary key, incremental ints aren't a great db strategy (because you can't shard your db) and so what you see in the prisma is how I build for prod.

it depends on your db you have a mogodb for example all ids can be uuids, you just need to have it unique across your schema which in the future could also incorporate more than one API for example

In your case, a _id could be defined in the redwood service layer as just taking the existing id - then new model types could have a real _id pretty easily.

At Artsy we did:

# An object with a Globally Unique ID
interface Node {
  # The ID of the object.
  __id: ID!
}

Where an __id was generally a base64 of id:api-service:type if I recall - https://github.com/artsy/metaphysics/blob/6439278795f6a15a1217c9baf42791c17eff76ec/src/schema/v2/object_identification.ts is the source of truth but it's pretty abstract

muhajirdev commented 2 years ago

re: incremental ints aren't a great

image

interesting, I just read about cursor-based pagination. that it needs a unique and serial column. (which is the nature of auto increment). While cuid / and uuid are generally not sequential (not sortable). So, it's a tradeofff? auto increment will be faster for reading. But cuid & uuid will be better for writingn in distributed environment?

Or do you think there's an approach that can take advantage of both solution? -> Unique and serial, but also easy to shard later on?

Thanks again for the idea & reference, very helpful

orta commented 2 years ago

You need a stable sort, not a sortable identifier - just a different frame of reference. createdAt on a model is usually my goto there (or something specific to the query)- but no cuids couldn't be sortable