在GraphQL中,输入输出和错误处理(Union、InputType)

我在株式会社mofmof工作的shwld,在Advent Calendar 2022的第24天分享了我用Next.js + 服务端TypeScript + 函数风格创建的干净应用程序,并写下了实现意图等内容。

我前日写了一篇关于在Railway上部署Next.js和graphile-worker的文章。

GraphQL的联合和输入类型

我之前在一个”Either”类型的文章中已经写过,”mutation”的返回值是一个”Union”。

比如说,创建账户的mutation可以是这个样子

export type CreateAccountMutationResult =
  | CreateAccountSuccessResult
  | InternalErrorResult
  | InvalidArgumentsResult
  | UnauthorizedResult;

GraphQL的特点是

union CreateAccountMutationResult =
    CreateAccountSuccessResult
  | InvalidArgumentsResult
  | UnauthorizedResult
  | InternalErrorResult

这样。

在调用此变更时,请在前端使用此mutation。

mutation AccountCreateButton_CreateAccount($input: CreateAccountInput!) {
  createAccount(input: $input) {
    ... on CreateAccountSuccessResult {
      result {
        ...AccountList_Result
      }
    }
  }
}

在React中,处理错误时需要获取正常完成的结果并使用ts-pattern等分支处理类型。

如何处理错误问题

在处理GraphQL错误时有一个问题需要考虑。

在GraphQL中,mutation和query的结果中有一个名为”errors”的字段,可以通过扩展该字段来返回错误信息。但是这次我们选择不采用这种方式。

作为理由,是因为错误的类型检查。对于errors的扩展无法进行类型标注,很难从前端进行处理。
通过返回union类型,可以在类型级别上了解到会得到什么结果,这样可以更加友好地使用TypeScript。

尽管检查多个类型会费时,但上述好处非常大。
此外,服务器端的实现本身也可以在类型级别上知道发生的任何错误,从而前端也能受益并保持一致性。

此外,还有一种设计策略是使用扩展的errors字段来处理未预定义的异常错误。但由于服务器端的实现本身就避免了抛出异常,因此本次我们完全没有从mutation中使用errors字段(仅在GraphQl的基础平台引发错误时使用errors字段)。

输入类型

变异(mutation)的参数已统一命名为input。

input CreateAccountInput {
  id: ID!
  name: String!
}
type Mutation {
  createAccount(input: CreateAccountInput!): CreateAccountMutationResult!
}

由于它能够轻松适应参数的变化,这就是为什么理由很简单。
为了推广这个规则,我们还使用PLOP生成了.graphql文件的模板。

下一次提前通知

明天我会进行总结。

广告
将在 10 秒后关闭
bannerAds