使用 GraphQL、Nexus 和 Prisma 优化 SQL 查询

问题描述

我正在尝试对包含关系的 GraphQL 查询应用一些 sql 优化。我使用 prisma (v. 2.24.1)、Nexus (v. 1.0.0)、nexus-plugin-prisma (v. 0.35.0) 和 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[]
}

当我尝试执行一个简单的 GraphQL 查询获取用户当前组织)时,prisma生成一个 sql 查询,该查询要求所有用户的列,即使我只要求提供 ID。

查询

{
  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

对于解析器,我使用 t.model 语法:

import { objectType } from "nexus"

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

就目前而言,我发现将 t.list.field 语法与 resolve 函数一起使用时,我可以从 info 参数中获取请求的用户字段,但似乎有没有将数据传递给prisma 客户端的优雅方式。

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()
  }
})

有没有办法使用来自 info 的数据并只查询 user.id 字段?

解决方法

有一个社区制作的插件,您可以使用它来处理所有举重工作:https://paljs.com/plugins/select/