Apollo Server 4 社交媒体后端图片上传GraphQL API开发方案求助
在Apollo Server 4中实现图片上传的GraphQL API(ES6方案)
Apollo Server 4不再内置文件上传支持,graphql-upload也因架构变更无法直接兼容,下面是基于Express和Formidable的ES6解决方案:
1. 安装依赖
npm install @apollo/server apollo-server-express express formidable graphql
2. 配置服务器与文件解析中间件
创建server.js文件,搭建Express服务并添加Formidable中间件处理multipart/form-data请求:
import { ApolloServer } from '@apollo/server'; import { expressMiddleware } from '@apollo/server/express4'; import express from 'express'; import { createReadStream } from 'fs'; import { mkdir, writeFile } from 'fs/promises'; import { IncomingForm } from 'formidable'; import path from 'path'; import { fileURLToPath } from 'url'; // 处理ES6模块的目录路径 const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); // 解析multipart请求的中间件 app.use(async (req, res, next) => { if (req.method !== 'POST' || !req.is('multipart/form-data')) { return next(); } const form = new IncomingForm({ uploadDir: path.join(__dirname, 'uploads'), keepExtensions: true, maxFileSize: 5 * 1024 * 1024, // 限制单文件5MB }); // 确保uploads目录存在 await mkdir(form.uploadDir, { recursive: true }); form.parse(req, (err, fields, files) => { if (err) return next(err); req.body = fields; req.files = files; next(); }); });
3. 定义GraphQL Schema
添加支持文件上传的Mutation类型:
const typeDefs = ` type Post { id: ID! content: String! imageUrl: String } type Mutation { createPost(content: String!, image: Upload): Post } `;
4. 实现Resolver处理文件上传
在Resolver中获取解析后的文件,完成存储并生成访问URL:
let postIdCounter = 1; const resolvers = { Mutation: { createPost: async (_, { content }, { req }) => { let imageUrl = null; if (req.files?.image) { const image = req.files.image; // 重命名文件避免冲突 const newFilename = `${Date.now()}-${image.originalFilename}`; const newFilePath = path.join(__dirname, 'uploads', newFilename); // 保存文件到指定目录 await writeFile(newFilePath, createReadStream(image.filepath)); // 生成静态访问URL(需配置静态托管) imageUrl = `/uploads/${newFilename}`; } // 示例:内存存储帖子,实际项目替换为数据库操作 const post = { id: postIdCounter++, content, imageUrl, }; return post; }, }, };
5. 启动服务并配置静态托管
将Apollo Server集成到Express,并托管uploads目录让前端可访问图片:
async function startServer() { const server = new ApolloServer({ typeDefs, resolvers }); await server.start(); app.use( '/graphql', express.json(), expressMiddleware(server, { context: async ({ req }) => ({ req }), }) ); // 静态托管uploads目录 app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); app.listen({ port: 4000 }, () => { console.log('🚀 Server running at http://localhost:4000/graphql'); }); } startServer().catch(err => console.error(err));
测试上传
在Apollo Sandbox中执行以下Mutation,选择本地图片作为image参数:
mutation CreatePost($content: String!, $image: Upload) { createPost(content: $content, image: $image) { id content imageUrl } }
注意事项
- 可根据需求调整文件大小限制、存储路径,或替换为云存储(如AWS S3)。
- 生产环境需添加文件类型校验(只允许图片格式)、错误捕获逻辑。
内容的提问来源于stack exchange,提问作者yaman jain
相关产品推荐
相关产品推荐

