如何使用 nexus-prisma 制作嵌套突变解析器

Tru*_*ufa 4 graphql prisma prisma-graphql nexus-prisma

我有以下数据模型:

type Job { 
    // ...
    example: String
    selections: [Selection!]
    // ...
}

type Selection { 
    ...
    question: String
    ...
}
Run Code Online (Sandbox Code Playgroud)

我这样定义我的对象类型:

export const Job = prismaObjectType({
  name: 'Job',
  definition(t) {
    t.prismaFields([
      // ...
      'example',
      {
        name: 'selections',
      },
      // ...
    ])
  },
})
Run Code Online (Sandbox Code Playgroud)

我这样做我的解析器:

t.field('createJob', {
  type: 'Job',
  args: {
    // ...
    example: stringArg(),
    selections: stringArg(),
    // ...
  },
  resolve: (parent, {
    example,
    selections
  }, ctx) => {
    // The resolver where I do a ctx.prisma.createJob and connect/create with example
  },
})
Run Code Online (Sandbox Code Playgroud)

所以现在在解析器中我可以接收 json 字符串形式的选择,然后解析它并连接/创建作业。

突变看起来像这样:

mutation {
  createJob(
    example: "bla"
    selections: "ESCAPED JSON HERE"
  ){
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更优雅的事情我可以做这样的事情:

mutation {
  createJob(
    example: "bla"
    selections: {
       question: "bla"
    }
  ){
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

或者

mutation {
  createJob(
    example: "bla"
    selections(data: {
      // ...
    })
  ){
    id
  }
}
Run Code Online (Sandbox Code Playgroud)

我注意到,使用Nexus-Prisma可以做到stringArg({list: true}),但不能真正做到物体。

我的主要问题是进行嵌套突变或全部连接的最优雅的方法是什么。

Dan*_*den 5

您可以使用inputObjectType,如文档中所示:

export const SomeFieldInput = inputObjectType({
  name: "SomeFieldInput",
  definition(t) {
    t.string("name", { required: true });
    t.int("priority");
  },
});
Run Code Online (Sandbox Code Playgroud)

确保将类型作为types您传递给的一部分包含在内makeSchema。然后你可以用它来定义一个参数,比如

args: {
  input: arg({
    type: "SomeFieldInput", // name should match the name you provided
  }),
}
Run Code Online (Sandbox Code Playgroud)

现在,参数值将作为常规 JavaScript 对象(而不是字符串)可供解析器使用。如果您需要输入对象的列表,或者想要使参数成为必需的,您可以使用与使用标量时提供的相同选项list来实现 - 、nullabledescription等。

这是一个完整的示例:

const Query = queryType({
  definition(t) {
    t.field('someField', {
      type: 'String',
      nullable: true,
      args: {
        input: arg({
          type: "SomeFieldInput", // name should match the name you provided
        }),
      },
      resolve: (parent, { input }) => {
        return `You entered: ${input && input.name}`
      },
    })
  },
})

const SomeFieldInput = inputObjectType({
  name: "SomeFieldInput",
  definition(t) {
    t.string("name", { required: true });
  },
});

const schema = makeSchema({
  types: {Query, SomeFieldInput},
  outputs: {
    ...
  },
});
Run Code Online (Sandbox Code Playgroud)

然后像这样查询:

query {
  someField(
    input: {
       name: "Foo"
    }
  )
}
Run Code Online (Sandbox Code Playgroud)

或者使用变量:

query($input: SomeFieldInput) {
  someField(input: $input)
}
Run Code Online (Sandbox Code Playgroud)