如何在Apollo GraphQL中添加联合类型?
在Apollo中实现联合类型(Worksheet/ApiError)
刚好你要的是让查询返回Worksheet或者ApiError的多态场景,我来给你梳理正确的实现方式,分类型定义和解析器两部分来说:
第一步:修正Schema类型定义
首先你原来的Schema有几个小问题:
- GraphQL的联合类型需要先显式定义Union类型,不能直接在字段里写
Worksheet | Error - 你定义的错误类型是
ApiError,不是Error,要对应上 Worksheet里的name String语法错误,缺冒号
修正后的typedefs.js应该是这样:
// typedefs.js export default [` schema { query: Query } # 定义联合类型,指定可能的返回类型 union WorksheetResult = Worksheet | ApiError type Query { # 查询字段返回这个联合类型 worksheet(id: String!): WorksheetResult } type Worksheet { id: String! name: String! # 补上冒号,建议加非空约束 } type ApiError { code: String! message: String! } `];
第二步:实现联合类型的解析器
Apollo需要知道返回的对象到底属于联合类型中的哪一个,所以必须在resolvers里添加resolveType函数来做类型判断。
假设你的数据源在查询成功时返回带id和name的Worksheet对象,失败时返回带code和message的ApiError对象,那你的resolvers.js可以这么写:
// resolvers.js export default { Query: { async worksheet(_, args, { loader }) { try { // 模拟从数据源获取Worksheet const worksheet = await loader.worksheet.load(args.id); if (!worksheet) { // 没找到时返回ApiError return { code: "NOT_FOUND", message: `Worksheet ${args.id} does not exist` }; } return worksheet; } catch (err) { // 捕获异常返回ApiError return { code: "INTERNAL_ERROR", message: err.message }; } }, }, // 给联合类型添加类型解析逻辑 WorksheetResult: { resolveType(obj) { // 根据对象的字段判断类型:有id就是Worksheet,有code就是ApiError if (obj.id) { return "Worksheet"; } if (obj.code) { return "ApiError"; } // 兜底返回null或者抛出错误 return null; }, }, };
第三步:查询时的类型分支
在前端查询的时候,需要用... on语法来区分不同类型的返回结果:
query GetWorksheet($id: String!) { worksheet(id: $id) { ... on Worksheet { id name } ... on ApiError { code message } } }
这样就能完美实现你要的“查询结果要么是Worksheet要么是ApiError”的多态场景啦~
内容的提问来源于stack exchange,提问作者Kenneth Truong
相关产品推荐
相关产品推荐

