如何在无中间件的Apollo Server v2.0中暴露HTTP GET文件下载端点
无需apollo-server-express,为无中间件Apollo Server v2添加文件下载端点
当然可以!在无中间件模式的Apollo Server v2中,完全不需要借助apollo-server-express就能添加用于文件下载的HTTP GET端点。核心思路是利用Apollo Server的底层依赖——Node.js原生http模块,手动创建服务器并插入自定义路由逻辑。
实现步骤
创建Apollo Server实例并获取请求处理器
不要直接调用server.listen(),而是先通过createHandler()获取Apollo的请求处理函数,这样我们就能把它集成到自定义的HTTP服务器中:const { ApolloServer, gql } = require('apollo-server'); const fs = require('fs'); const http = require('http'); const url = require('url'); // 定义你的GraphQL schema和resolvers const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: () => 'Hello world!', }, }; const apolloServer = new ApolloServer({ typeDefs, resolvers }); // 获取Apollo的请求处理器 const apolloHandler = apolloServer.createHandler();手动创建HTTP服务器并添加下载路由
用Node.js原生http.createServer()创建服务器,在请求回调中判断路径:如果是下载端点,就处理文件下载逻辑;否则交给Apollo的处理器:const httpServer = http.createServer(async (req, res) => { // 解析请求URL(支持带参数的场景,比如/download?id=123) const parsedUrl = url.parse(req.url, true); // 匹配下载端点的GET请求 if (req.method === 'GET' && parsedUrl.pathname === '/download') { // 示例:根据参数获取文件(这里可以替换成你的业务逻辑) const fileId = parsedUrl.query.id; const filePath = `./files/${fileId}.pdf`; // 假设文件存储路径 // 检查文件是否存在 if (!fs.existsSync(filePath)) { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('File not found'); return; } // 设置下载响应头 res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `attachment; filename="file-${fileId}.pdf"`); // 流式传输文件到客户端 const fileStream = fs.createReadStream(filePath); fileStream.pipe(res); return; } // 其他请求交给Apollo处理 await apolloHandler(req, res); });启动服务器
最后启动自定义的HTTP服务器,同时监听GraphQL和下载端点:const PORT = 4000; httpServer.listen(PORT, () => { console.log(`🚀 GraphQL server ready at http://localhost:${PORT}/graphql`); console.log(`📥 Download endpoint ready at http://localhost:${PORT}/download`); });
关键细节说明
- 路由灵活性:可以通过
url.parse()解析请求参数,支持更复杂的下载逻辑(比如根据用户权限返回不同文件)。 - 错误处理:一定要添加文件存在性检查、流式传输错误捕获等逻辑,避免服务器崩溃。
- 文件类型适配:根据不同的文件类型修改
Content-Type头(比如图片用image/png,Excel用application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)。
这种方式完全基于Node.js原生能力,不需要引入额外的中间件依赖,完美适配你的需求。
内容的提问来源于stack exchange,提问作者Raghavendar
相关产品推荐
相关产品推荐

