GraphQL中处理Union Type时复用Resolver的实现问题
解决方案:让Apollo自动区分Car.engine的发动机类型并返回对应数据
完全可以实现需求,不过你当前的代码存在几处需要调整的问题,以下是具体的修正和实现思路:
1. 先修正Query字段的定义与实现
你当前定义的Query.dieselEngine和Query.petrolEngine没有接收车型参数的能力,而且resolver的参数写法有误(Query resolver的第一个参数是root对象,第二个才是传入的参数)。首先调整类型定义:
type Query { cars: [Car] # 增加车型参数,用于单独查询某车型的对应发动机 dieselEngine(model: String!): DieselEngine petrolEngine(model: String!): PetrolEngine }
对应的Query resolver也要修正,改为接收参数:
const resolvers = { Query: { cars: () => [{ model: 'bmw' }, { model: 'fiat' }], dieselEngine: (_, { model }) => engines[model], petrolEngine: (_, { model }) => engines[model], }, // ...其他resolver };
2. 实现Car.engine的自动区分逻辑
在Car.engine的resolver中,直接根据父对象(当前Car的model)从engines对象中取出对应数据即可,返回后__resolveType会自动识别它是柴油还是汽油发动机类型:
Car: { engine: (parent) => { // parent是当前Car对象,直接取出对应车型的发动机数据 return engines[parent.model]; } }
如果确实需要复用Query中定义的dieselEngine或petrolEngine resolver函数(比如这些函数包含复杂业务逻辑),也可以先判断发动机类型,再手动调用对应的函数:
Car: { engine: (parent) => { const engineData = engines[parent.model]; // 根据数据判断类型,调用对应的Query resolver if (engineData.dieselType) { return resolvers.Query.dieselEngine(null, { model: parent.model }); } else { return resolvers.Query.petrolEngine(null, { model: parent.model }); } } }
3. 完整修正后的代码
import { ApolloServer } from '@apollo/server'; import { startStandaloneServer } from '@apollo/server/standalone'; const typeDefs = `#graphql type Car { model: String engine: CarEngine } union CarEngine = DieselEngine | PetrolEngine type DieselEngine { capacity: Float dieselType: String } type PetrolEngine { capacity: Float petrolType: String } type Query { cars: [Car] dieselEngine(model: String!): DieselEngine petrolEngine(model: String!): PetrolEngine } `; const engines = { bmw: {capacity: 2.0, dieselType: 'L'}, fiat: {capacity: 1.6, petrolType: '95'}, } const resolvers = { Query: { cars: () => [{ model: 'bmw' }, { model: 'fiat' }], dieselEngine: (_, { model }) => engines[model], petrolEngine: (_, { model }) => engines[model], }, Car: { engine: (parent) => { return engines[parent.model]; } }, CarEngine: { __resolveType: (obj) => { if (obj?.dieselType) return 'DieselEngine'; return 'PetrolEngine'; } } }; const server = new ApolloServer({ typeDefs, resolvers, }); const { url } = await startStandaloneServer(server); console.log(`🚀 Server ready at ${url}`);
关键说明
CarEngine的__resolveType函数会自动根据返回对象的字段(dieselType或petrolType)判断具体类型,Apollo会据此返回对应类型的字段数据。Car.engineresolver的核心是通过父对象的model字段关联到对应的发动机数据,无需手动调用Query的其他字段(除非有特殊业务需求),这种方式更直接高效。
内容的提问来源于stack exchange,提问作者eugenedrvnk
相关产品推荐
相关产品推荐

