当没有数据返回时,GraphQL 突变返回类型应该是什么?

Mar*_*rio 15 javascript rest apollo graphql apollo-server

我有一个 Apollo GraphQL 服务器,我有一个删除记录的突变。此更改接收资源的 UUID,调用 REST(Ruby on Rails)API,当删除成功时,该 API 仅返回成功的 HTTP 代码和空正文(204 无内容)以及带有错误的 HTTP 错误代码删除不起作用时的消息(404 或 500,典型的 REST 删除端点)。

在定义 GraphQL 突变时,我必须定义突变返回类型。突变返回类型应该是什么?

input QueueInput {
  "The queue uuid"
  uuid: String!
}


deleteQueue(input: QueueInput!): ????????
Run Code Online (Sandbox Code Playgroud)

我可以使它与几种不同类型的返回(布尔值、字符串等)一起工作,但我想知道什么是最佳实践,因为我尝试过的返回类型都没有感觉是正确的。我认为重要的是,在调用突变后,在客户端我有一些关于如果事情进展顺利(API 返回 204 不是内容)或如果发生一些错误(API 返回 404 或 500)发生了什么的信息,并且最好有一些关于错误。

Dan*_*den 13

GraphQL 中的字段必须始终具有类型。GraphQL 有null的概念,但 null 本身并不是一种类型——它只是代表缺乏价值。

GraphQL 中没有“void”类型。但是,默认情况下类型可以为空,因此无论字段的类型如何,您的解析器都不会返回任何内容,并且该字段将简单地解析为 null。所以你可以

type Mutation {
  deleteQueue(input: QueueInput!): Boolean #or any other type
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您想要一个专门表示 null 的标量,您可以创建自己的.

const { GraphQLScalarType } = require('graphql')

const Void = new GraphQLScalarType({
  description: 'Void custom scalar',
  name: 'Void',
  parseLiteral: (ast) => null,
  parseValue: (value) => null,
  serialize: (value) => null,
})
Run Code Online (Sandbox Code Playgroud)

然后做

type Mutation {
  deleteQueue(input: QueueInput!): Void
}
Run Code Online (Sandbox Code Playgroud)

也就是说,返回某些东西是常见的做法。对于删除,通常返回已删除的项目或至少返回其 ID。这有助于客户端的缓存管理。返回某种变异有效负载类型以更好地封装客户端错误也变得越来越普遍。

您可以在“有效负载”类型中包含任意数量的字段,如下所示:

type Mutation {
  deleteQueue(input: QueueInput!): DeleteQueuePayload
}

type DeleteQueuePayload {
  # the id of the deleted queue
  queueId: ID

  # the queue itself
  queue: Queue

  # a status string
  status: String

  # or a status code
  status: Int

  # or even an enum
  status: Status

  # or just include the client error
  # with an appropriate code, internationalized message, etc.
  error: ClientError

  # or an array of errors, if you want to support validation, for example
  errors: [ClientError!]!
}
Run Code Online (Sandbox Code Playgroud)

DeleteQueuePayload 甚至可以是不同类型的联合,使客户端能够使用__typename来确定突变的结果。

但是,您公开什么信息取决于您的特定需求,而您采用的特定模式归结为意见。

有关其他讨论和示例,请参见此处此处