如何在使用.graphql文件的Apollo Server 2.0中实现文件上传功能?
我之前在Apollo Server 2.x里也碰到过一模一样的问题——用.graphql文件管理schema时,内置的Upload标量总是无法正常工作,自己定义还会冲突。其实核心原因是:从文件加载的纯文本schema只是定义了类型结构,并没有关联Apollo内置的Upload标量的具体实现,所以需要我们手动把它映射到resolvers中。
具体解决步骤:
导入必要模块
首先确保你导入了Apollo Server提供的Upload标量,以及加载文件和解析schema所需的工具:const { ApolloServer, gql, Upload } = require('apollo-server'); const fs = require('fs');加载并解析.graphql文件
用fs.readFileSync加载你的schema文件,再通过gql函数把纯文本解析成Apollo能识别的DocumentNode类型:// 加载你的schema文件 const schemaContent = fs.readFileSync('./your-schema.graphql', 'utf8'); // 解析为GraphQL schema对象 const typeDefs = gql(schemaContent);在resolvers中关联Upload标量
不需要在你的.graphql文件里定义scalar Upload(这会和Apollo内置的冲突),直接在resolvers里把Apollo的Upload标量映射进去即可:const resolvers = { // 关键:把Apollo内置的Upload标量绑定到schema的Upload类型上 Upload: Upload, // 你的其他resolvers逻辑,比如文件上传的处理函数 Mutation: { uploadFile: async (_, { file }) => { // 获取文件流和元数据 const { createReadStream, filename, mimetype } = await file; // 这里写你的文件处理逻辑(比如保存到本地或云存储) // ... return { filename, mimetype }; }, }, };初始化Apollo Server
把解析好的typeDefs和包含Upload标量的resolvers传入ApolloServer即可:const server = new ApolloServer({ typeDefs, resolvers }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
你的.graphql文件示例
在schema文件里直接使用Upload作为字段类型,不需要额外定义标量:
type File { filename: String! mimetype: String! } type Mutation { # 直接使用Upload类型 uploadFile(file: Upload!): File! }
为什么这样能解决问题?
Apollo Server内置的Upload标量已经包含了文件上传所需的所有逻辑(比如处理multipart请求、解析文件流),但从文件加载的纯文本schema只是声明了"有个叫Upload的标量",并没有关联到具体的实现。通过在resolvers里把Upload: Upload映射进去,我们就告诉了schema:这个Upload类型对应的实现是Apollo提供的那个内置标量。
内容的提问来源于stack exchange,提问作者Nezih

