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

如何在Apollo Server中共享自定义typeDefs、枚举及Message类型?

在Apollo Server中共享自定义TypeDefs与枚举,解决重复类型定义问题

嘿,我来帮你搞定这个问题!你遇到的There can be only one type named "Message"报错,本质是GraphQL的Schema不允许同名类型被重复定义——你在user和product的typeDefs里各写了一遍Message,自然会冲突。下面分两部分讲清楚怎么共享类型和枚举:

一、共享自定义TypeDefs(以Message为例)

核心思路是把公共类型抽离到单独文件,再在业务模块中引用,最后合并所有TypeDefs到Apollo Server。

步骤1:抽离公共类型

新建一个专门存放公共类型的文件,比如common.typeDefs.js,把Message类型只在这里定义一次:

# common.typeDefs.js
type Message {
  message: String!
}

步骤2:修改业务模块的TypeDefs

在user和product的TypeDefs里,只保留各自的业务逻辑,不要再重复定义Message,直接引用即可:

# user.typeDefs.js
type Mutation {
  logout: Message! # 直接用公共的Message类型
}
# product.typeDefs.js
type Mutation {
  addProduct(name: String!, price: Float!): Message! # 同样引用公共类型
}

步骤3:合并TypeDefs到Apollo Server

初始化Apollo Server时,把公共TypeDefs和业务TypeDefs放在一个数组里传入,Apollo会自动合并成一个合法的Schema:

const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone');

// 导入所有TypeDefs
const commonTypeDefs = require('./common.typeDefs');
const userTypeDefs = require('./user.typeDefs');
const productTypeDefs = require('./product.typeDefs');

// 合并Resolver(注意:Message类型不需要单独写Resolver,只要业务Mutation返回对应结构即可)
const resolvers = {
  Mutation: {
    logout: () => ({ message: 'Logout successful!' }),
    addProduct: (_, { name, price }) => ({ message: `Product "${name}" added successfully!` })
  }
};

// 初始化Server
const server = new ApolloServer({
  typeDefs: [commonTypeDefs, userTypeDefs, productTypeDefs],
  resolvers,
});

// 启动服务
startStandaloneServer(server, { listen: { port: 4000 } })
  .then(({ url }) => console.log(`Server ready at ${url}`));

这样就能完美解决重复定义的问题啦!

二、共享枚举类型

共享枚举的逻辑和共享自定义类型完全一致:

步骤1:在公共文件中定义枚举

还是在common.typeDefs.js里添加枚举:

# common.typeDefs.js
type Message {
  message: String!
}

# 新增共享枚举
enum ProductStatus {
  IN_STOCK
  OUT_OF_STOCK
  DISCONTINUED
}

步骤2:在业务模块中引用

比如在product的TypeDefs里使用这个枚举:

# product.typeDefs.js
type Product {
  id: ID!
  name: String!
  status: ProductStatus! # 直接引用公共枚举
}

type Mutation {
  addProduct(name: String!, price: Float!): Message!
}

步骤3:合并到Server

同样把包含枚举的公共TypeDefs加入数组,Apollo会自动处理枚举的共享。

三、额外小提示

  • 如果你的项目用ES Modules(import/export),只需要把require换成import即可,逻辑完全相同
  • 如果你用graphql-tag的gql模板字符串定义TypeDefs,抽离和合并的方式也一样——把公共的gql模板单独导出,再和业务模板一起放进数组
  • 确保所有公共类型/枚举只在一个地方定义,其他地方只做引用,避免重复

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:38:15