sqlpostgresqlgraphqlrelayjshasura

Efficient GraphQL mutation (insert) with nested, non-tree relationship objects


I'm using Relay endpoints generated in Hasura, connected to a PostgreSQL database.

Suppose there are three objects a, b, and c.

This is the essence of the Relay GraphQL schema for these objects:

type a implements Node {
  id: ID!
  bs(...): [b!]!
  bs_connection(...): bConnection!
  cs(...): [c!]!
  cs_connection(...): cConnection!
}

type b implements Node {
  id: ID!
  a: jargon!
  a_id: Int!
  c: translation
  c_id: Int
}

type c implements Node {
  id: ID!
  b: comment
  b_id: Int!
  a: jargon!
  a_id: Int!
}

I want to insert an object a with b and c altogether:

a --→ b
  \   ↑
   -→ c

But if I try the followings:

mutation AttemptMutation1 {
  insert_a_one(object: {bs: {data: {c: {data: {}}}}}) {
    id
  }
}

mutation AttemptMutation2 {
  insert_a_one(object: {cs: {data: {b: {data: {}}}}}) {
    id
  }
}

neither works, emitting errors like

Not-NULL violation. null value in column \"b_id\" of relation \"c\" violates not-null constraint

I'm currently resorting to

  1. insert a with b object nested,
  2. insert c with b ID, and
  3. update b with c ID. Here I'm also not sure why step 2 does not set c ID for b automatically. This makes 3 GraphQL queries which really hurts the performance. Ideally I would like to perform this operation in a single transaction to make it robust.

What is the recommended way to deal with this kind of mutation?


Solution

  • I came to the conclusion that this is exactly the case where UUIDs as PKs are the solution. The root cause of this was not knowing the IDs prior to the DB lookup, and by migrating the DBs to use UUIDs as PKs, I have solved this problem.

    There are a lot of derived problems related to this after some research, e.g., using a custom @export directive to use ID as a runtime variable, updating with nested objects, nested relationships in mutation, etc.

    But I believe the client being able to choose IDs seem like a occam's razor solution for this problem.