GraphQL突变的响应应该是什么?

时间:2018-11-09 00:27:19

标签: javascript graphql

我正在编写GraphQL服务器,想知道突变带来的响应是什么?对于查询,很明显:响应包含所请求的内容。但是,对于突变,响应应该是什么样?响应是否应该仅由String消息组成,让消费者知道突变是否成功且没有错误?还是应该将响应作为它们变异的对象?

1 个答案:

答案 0 :(得分:1)

GraphQL不会强制这种方式,但是流行的惯例是返回对象

使用REST,通常的理解是被突变的对象应作为对象所处的新状态返回。该约定也已延续到GraphQL,所以我想说在大多数情况下,您想返回宾语。

GraphQL documentation似乎也加强了这一点:

type Mutation {
  createMessage(input: MessageInput): Message
  updateMessage(id: ID!, input: MessageInput): Message
}

在这种情况下,createMessageupdateMessage取一个MessageInput并返回更新的或新的Message对象。

这也具有关键的实际好处!对于流行的GraphQL框架(如Apollo),返回结果意味着Apollo将automatically integrate the updated result放入其缓存中,以便以后更快地进行检索和呈现。

在某些情况下您不想这样做吗?绝对是如果要删除对象,则可能只想返回更简单的返回类型,例如ID或标识操作已完成的字符串。

还有一些没有自然对象返回的操作,因为它们不直观地绑定到CRUD操作中(例如promoteUser)。在REST中,通常需要将该操作包装到一个抽象对象(例如POST /promoteUserRequest)中,以使其在技术上是惯用的,但是在GraphQL中,您可以更加灵活(返回用户有效,或者也可以返回只是一个字符串确认)。

还有其他信仰阵营,倡导这种设计:

type RootMutation {
  createTodo(input: CreateTodoInput!): CreateTodoPayload
  toggleTodoCompleted(input: ToggleTodoCompletedInput!): ToggleTodoCompletedPayload
  updateTodoText(input: UpdateTodoTextInput!): UpdateTodoTextPayload
  completeAllTodos(input: CompleteAllTodosInput!): CompleteAllTodosPayload
}

在此example from the Apollo blog中,它不返回泛型Todo类型,而是返回特定于每个突变的自定义类型。有人认为,这种突变输入响应的1对1映射是一种更好的方法,因为它使您可以编辑单个突变而不必担心影响其他解析程序的返回/输入值。有时也用于查询。

最后,请记住这里的另一个GraphQL好处:无论您决定返回什么内容,客户端都只需要从结果中检索它即可。客户端可以自由执行更改,并请求全部,部分或不请求任何响应类型。为了进行比较,在REST下,通常会迫使您接收整个响应。

总体而言,我想返回对象的情况要多得多,但是没有严格的规定,因此您可以选择最适合自己的API的