Handling Connections with prisma-bindings?

prisma

#1

I’m not sure if I’m resolving these Connection fields correctly as it seems kind of clumsy the way I’m doing it:

Here’s my datamodel:

type User {
   id: ID! @unique
   name: String! @unique
}

type Database {
  id: ID! @unique
  name: String! @unique
}

type DatabaseGrant {
  id: ID! @unique
  database: String!
  user: String!
  permission: [DatabasePermission]
}

enum DatabasePermission {
  SHOW_DATABASE
}

When I query for DatabaseGrants using the prisma endpoint, I correctly get back:

{
  "data": {
    "databaseGrants": [
      {
        "id": "cji69drh4003f0879zjvs5ob5",
        "permission": [
          "SHOW_DATABASE"
        ]
      }
    ]
  }
}

But on my graphql server, I get:

{
  "data": {
    "databaseGrants": [
      {
        "id": "cji69drh4003f0879zjvs5ob5",
        "permission": null
      }
    ]
  }
}

The resolver for databaseGrants is just:

  Query: {
    databaseGrants(parent, args, ctx, info) {
      return ctx.db.query.databaseGrants()
    },
  }

So I figured, permission is not resolving correctly because the prisma-binding queries the DatabaseGrant table only, so I have to manually resolve the connection for that permission field, is that correct?

And if so, is this the correct way to resolve it?

  DatabaseGrant: {
    async permission(parent, args, ctx, info) {
      const data = await ctx.db.query.databaseGrantsConnection(
        {
          where: {
            id: parent.id
          }
        },
        `{
          edges {
            node {
              permission
            }
          }
        }`
      )
      return data.edges[0].node.permission
    }
  }

Thanks, sorry for the long post. :frowning_face:


Building resolvers for linksConnection query and other nested relations
#2

Hey @tabsnotspaces :wave:,

I think you can achieve your goal a lot more easily. You are right, in a way, about Prisma only querying one table. Nevertheless, you must not forget that Prisma is still a GraphQL server itself; therefore, you can nest the fields you want to access.

The reason, why your query doesn’t work the way it should, is that Prisma doesn’t receive the information about the desired fields you want to access - permission in particular.

In case of Prisma endpoint, Prisma receives the original request;

query {
  databaseGrants {
    id
    permission
  }
}

Because it knows that you want to access permission as well as id it’s going to return both of them. Now, in the following case, id is a scalar field. Scalar fields get queried by default with no info parameter required. In a way, you could translate your resolver into the following “native” query.

Query: {
  databaseGrants(parent, args, ctx, info) {
    return ctx.db.query.databaseGrants()
  },
}
query {
  databaseGrants {
    id #scalar
  }
}

permission, on the other hand, is an array of enums. Arrays are not treated the same way as scalar fields are; therefore your server will receive an only partial response - null for permission.

To fix this, forward the info object your resolver has received to Prisma like this;

Query: {
  databaseGrants(parent, args, ctx, info) {
    return ctx.db.query.databaseGrants({}, info)
  },
}

This will ensure that the info object going through your server to Prisma includes all the fields your server has requested.

Hope this solves your question :slightly_smiling_face:


#3

Woah! Thanks for that explanation, that was extremely valuable. Cheers!