简体   繁体   中英

Optimize SQL queries using GraphQL, Nexus and Prisma

I'm trying to apply some SQL optimization for GraphQL queries containing relations. I use Prisma (v. 2.24.1), Nexus (v. 1.0.0), nexus-plugin-prisma (v. 0.35.0) and graphql (v. 15.5.0).

schema.prisma:


model User {
  id             Int           @id @default(autoincrement())
  username       String
  firstName      String?
  lastName       String?
  password       String
  email          String
  organization   Organization  @relation(fields: [organizatonId], references: [id])
  organizatonId  Int
}

model Organization {
  id        Int     @id @default(autoincrement())
  name      String  @unique
  users     User[]
}

When I try to perform a simple GraphQL query, which fetches the current organization with users, prisma generates an SQL query which asks for all of the users' columns even though I ask only for the ID.

query:

{
  organization {
    id
    name
    users {
      id
    }
  }
}

sql:

SELECT "public"."Organization"."id", "public"."Organization"."name" FROM "public"."Organization" WHERE 1=1 LIMIT $1 OFFSET $2
SELECT "public"."Organization"."id" FROM "public"."Organization" WHERE "public"."Organization"."id" = $1 LIMIT $2 OFFSET $3
SELECT "public"."User"."id", "public"."User"."username", "public"."User"."firstName", "public"."User"."lastName", "public"."User"."password", "public"."User"."email", "public"."User"."organizatonId" FROM "public"."User" WHERE "public"."User"."organizatonId" IN ($1) OFFSET $2

For the resolver I use the t.model syntax:

import { objectType } from "nexus"

export const Organization = objectType({
  name: 'Organization',
  definition(t) {
    t.model.id()
    t.model.name()
    t.model.users()
  }
})

As for now, I've found that when using the t.list.field syntax with the resolve function I can get the requested user fields from the info argument, but it seems there is no elegant way to pass that data to prisma client.

t.list.field('users', {
  type: 'User',
  resolve(org, args, ctx, info) {
    // info contains the requested fields
    return ctx.prisma.organization.findUnique({
       where: { id: org.id }
    }).users()
  }
})

Is there a way to use the data from info and query only the user.id field?

There's a community made plugin that you can use that handles all the heavy lifting: https://paljs.com/plugins/select/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM