在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文件的模板。
下一次提前通知
明天我会进行总结。