为什么我应该为 GraphQL 突变响应类型使用接口?

Why should I use an interface for a GraphQL mutation response type?

在阅读Apollo Server文档时,推荐使用突变响应接口进行突变:

In order to provide consistency across a schema, we suggest introducing a MutationResponse interface which can be implemented on every mutation response in a schema and enables transactional information to be returned in addition to the normal mutation response object.

https://www.apollographql.com/docs/apollo-server/essentials/schema.html

我了解接口对于具有 events 接口的用例的好处,然后您有不同类型的事件,例如音乐会、会议等。我的理解是一个界面将允许您使用单个查询搜索所有事件,例如,返回多种类型的事件。

我很困惑为什么应该将接口用于突变响应以及与标准响应类型相比有什么好处?

与联合体一样,接口是一种抽象类型,它允许一个字段 return 多种类型之一。来自规范:

Fields which yield an interface are useful when one of many Object types are expected, but some fields should be guaranteed.

但是,接口还强制实现类型具有一组特定的字段和参数。可以在规范中找到确切的规则 here,但归结为:

  • 如果接口有一个字段,实现类型也必须有那个字段
  • 实现类型还必须对这些字段中的任何一个具有相同的参数(比如字段,它可以添加额外的参数,但必须至少实现与接口相同的参数)
  • 这些必填字段和参数的类型必须与接口匹配
  • 如果必填字段或接口的类型为 Non-Null,则其在实现类型上也必须为 Non-Null(尽管反之则不然)

通过创建一个接口并让多个类型实现它,您可以有效地创建一个安全网,帮助您确保跨相关类型的结构一致。假设我们按照 Apollo 文档中的建议实现了一些没有接口的响应类型:

type UpdateUserMutationResponse {
  code: String!
  success: Boolean!
  message: String!
  user: User
}

type UpdatePostMutationResponse {
  code: String!
  success: Boolean!
  message: String
  post: Post
}

乍一看,这些类型是按照我们的预期定义的——我们有 codesuccessmessage 字段,以及与该响应相关的任何其他字段.但是,我们有一个类型,不小心使 UpdatePostMutationResponse 上的 message 字段可为空。虽然这可能是无害的,但如果我们确实碰巧在我们的解析器中忽略了消息,它可能会被忽视直到晚些时候(希望在 QA 期间,但可能在生产中!)。

不过,如果我们让这些类型实现一个 MutationResponse 接口,我们就可以确保即使存在任何不一致,我们的架构也不会构建。

这样,即使我们从不使用 MutationResponse 作为字段的 return 类型,我们仍然可以从使用接口中受益。