You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.engine resolver的核心是通过父对象的model字段关联到对应的发动机数据,无需手动调用Query的其他字段(除非有特殊业务需求),这种方式更直接高效。

内容的提问来源于stack exchange,提问作者eugenedrvnk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:02:10