GraphQL 是一种用于 API 构建的查询语言和运行时环境,它的强大之处在于可以根据客户端的需求精确地获取数据。在许多应用程序中,文件上传和下载是必需的功能之一。本文将介绍如何在 GraphQL 中处理文件上传及下载。
文件上传
在 GraphQL 中处理文件上传需要使用 GraphQL Upload 这个扩展库。它提供了一个 Upload
标量类型,可以用于处理文件上传。
安装及配置
首先,需要安装 graphql-upload
库:
npm install graphql-upload
然后,在 GraphQL 的 ApolloServer
中配置 graphql-upload
:
// javascriptcn.com 代码示例 const { ApolloServer } = require('apollo-server'); const { GraphQLUpload } = require('graphql-upload'); const resolvers = { /* resolvers */ }; const typeDefs = /* type definitions */; const server = new ApolloServer({ typeDefs, resolvers, uploads: false, // 禁用文件上传 // 配置文件上传 async context({ req }) { return { req, // 限制文件大小为 10 MB maxFileSize: 10000000, // 限制文件数量为 5 maxFiles: 5, }; }, }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
在上面的例子中,我们将文件大小限制为 10 MB,文件数量限制为 5。
编写上传查询
在客户端发起文件上传请求时,需要使用 FormData
对象将文件上传到服务端。以下是一个示例:
// javascriptcn.com 代码示例 const UPLOAD_FILE = gql` mutation UploadFile($file: Upload!) { uploadFile(file: $file) { filename mimetype encoding url } } `; const fileInput = document.querySelector('#file-input'); const file = fileInput.files[0]; const formData = new FormData(); formData.append('file', file); client.mutate({ mutation: UPLOAD_FILE, variables: { file: formData.get('file') }, });
实现上传功能
在服务端实现文件上传功能的代码如下:
// javascriptcn.com 代码示例 const { createWriteStream } = require('fs'); const { GraphQLUpload } = require('graphql-upload'); const UPLOAD_DIR = './uploads'; const resolvers = { Upload: GraphQLUpload, Mutation: { async uploadFile(parent, { file }, { req }) { const { createReadStream, filename, mimetype, encoding } = await file; const stream = createReadStream(); const filePath = `${UPLOAD_DIR}/${filename}`; const writeStream = createWriteStream(filePath); stream.pipe(writeStream); return { filename, mimetype, encoding, url: `http://localhost:4000/${filePath}`, }; }, }, };
在上面的例子中,我们获取了上传文件的元数据,然后将文件写入到指定的目录中。最后,返回文件的元数据和 URL。
文件下载
在 GraphQL 中处理文件下载需要使用 express 库。以下是示例代码:
// javascriptcn.com 代码示例 const express = require('express'); const { ApolloServer } = require('apollo-server-express'); const app = express(); const resolvers = { /* resolvers */ }; const typeDefs = /* type definitions */; const server = new ApolloServer({ typeDefs, resolvers, }); server.applyMiddleware({ app }); // 处理文件下载 app.get('/downloads/:filename', (req, res) => { const { filename } = req.params; res.download(`./uploads/${filename}`); }); app.listen({ port: 4000 }, () => console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`) );
在上面的例子中,我们使用 express
库处理文件下载请求。当客户端访问 /downloads/:filename
路径时,服务端会将指定的文件发送给客户端。
编写下载查询
在客户端发起文件下载请求时,需要使用 window.open
方法打开文件下载链接。以下是一个示例:
// javascriptcn.com 代码示例 const DOWNLOAD_FILE = gql` query DownloadFile($filename: String!) { downloadFile(filename: $filename) } `; const downloadFile = async (filename) => { const { data } = await client.query({ query: DOWNLOAD_FILE, variables: { filename }, }); window.open(data.downloadFile); };
实现下载功能
在服务端实现文件下载功能的代码如下:
const resolvers = { Query: { downloadFile(parent, { filename }) { return `http://localhost:4000/downloads/${filename}`; }, }, };
在上面的例子中,我们返回文件下载链接。
总结
本文介绍了如何在 GraphQL 中处理文件上传及下载。在文件上传方面,我们使用了 graphql-upload
扩展库,并在服务端实现了文件上传功能。在文件下载方面,我们使用了 express
库,并在服务端实现了文件下载功能。希望本文能够对你有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6568c35fd2f5e1655d16caf9