在现代 Web 应用中,文件上传已经成为了必不可少的一部分。如果使用 GraphQL 技术栈来开发应用的话,上传文件将会是一个更加引人注目的问题。好在社区中出现了一些非常不错的解决方案来支持文件上传,其中就包括了 @gutenye/apollo-upload-server 这个 npm 包。在此篇文章中,我们将会深入了解如何使用这个 npm 包。
什么是 @gutenye/apollo-upload-server?
@gutenye/apollo-upload-server 是一个用于从客户端上传文件到服务器的 Apollo Server 托管服务的集成解决方案。它允许用户使用 GraphQL 请求/响应框架,并且通过使用 multipart/form-data 来支持多文件上传。
安装
使用 npm 安装 @gutenye/apollo-upload-server 包。
npm i @gutenye/apollo-upload-server
使用方法
创建 multer-storage
在首先必须要创建 multer-storage,来设置上传文件的 destination 和 file name。在这一步中,我们采用可回调函数的方式来注册存储器。这样可以得到更加灵活的设置方式,允许我们在将来更改存储策略。
-- -------------------- ---- ------- ----- ------ - ------------------ ----- ------- - -------------------- ------------ ----- ----- --- -- - -------- ------------- -- --------- ----- ----- --- -- - ----- ------------ - ---------- - --- - ------------------------ - ----- -------- ------------ - --- - ------------------- -- --- ----- ------ - -------- -------- ------- ---
在这段示例代码中,我们使用磁盘存储器 multer.diskStorage 来创建 upload 的存储。文件将被存储在根目录下的 /uploads 子目录中。文件名将使用带有时间戳前缀的原始文件名创建。时间戳前缀旨在避免同时上传多个具有相同文件名的文件的可能性。
上传文件到服务器
-- -------------------- ---- ------- ----- - ------------ - - ------------------------- ----- - -------------------- - - ----------------------------------------- ----- - -------- - - -------------------- ----- - --------- - - ----------------------- -- ------ --- ------ ------ ----- ------ - --- -------------- --------- ---------- -------- ------ --- ------------------------ ---- ----- ----------- --- ------------------ ------------------------------ -- ---- --- ------ ------ ------- ---------
在这段代码中,我们使用 Apollo Server 来创建我们的 GraphQL API。然后我们使用 applyMiddleware 函数来将 Apollo Server 和我们的 Express 应用程序一起使用,并将 GraphQL API 映射到 /graphql 路径。
接下来,我们使用将 multer 存储对象 upload 作为参数传递给 graphqlUploadExpress 函数来设置我们的文件上传服务。graphqlUploadExpress 函数返回一个 Express 中间件,允许我们将图像上传服务映射到 /upload 路径。这样,我们就建立了 Express 路径与 GraphQL 路径之间的联系。
GraphQL TypeDefs
在 TypeDefs 中,定义我们的 schema 文件,包含 Query 和 Mutation。
-- -------------------- ---- ------- ---- ---- - --------- ------- --------- ------- --------- ------- ---- ------- - ---- -------- - ------------------ --------- ----- --------------------- ------------ -------- -
GraphQL Resolvers
在 Resolvers 中,实现我们的逻辑。
-- -------------------- ---- ------- ----- - ----------------- - - -------------- ----- ------------- - -------------------------- ----- ------------ - ----- -------- - ---- -- -- - --- ------ - ----- ----- - ----------------- --------- --------- -------- - - ----- ----- ----- --- ----------------- ------- -- ------------------ ------------------------------------------------------------ ------------- -------- ------------ ------- ------------ -- - ------ - - --------- --------- --------- --- -- --- ------ ------- -- ----- -------------- - ----- -------- - ----- -- -- - --- ------ - --- ----- - ----------------- --------- --------- -------- - - ----- --------- ----- --- ----------------- ------- -- ------------------ ------------------------------------------------------------ ------------- -------- ------------ ------- ------------ -- - --- ---- - - --------- --------- --------- --- -- ------------------ --- ------ ------- -- -------------- - - -------------- ------ --- --------- - ------------- --------------- -- --
在这段代码中,我们先引入了 nodejs 的 fs 模块,用于将上传的文件流写入磁盘。作为 GraphQLUpload 的引用模块,使用 upload 标记来从请求传递中获取上传的文件流。在每个 Resolver 中,将该文件流期望到存在的字段的 key 中(这里是 createReadStream);
返回包含有文件上传信息的对象:
result = { filename, mimetype, encoding, url };
简单测试
启动本地服务器后,可以选择任意一种方式来验证我们的 Resolver:
- 通过 curl 发送查询请求
curl -X POST -H "Content-Type: multipart/form-data" -F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { filename, mimetype, encoding, url } }", "variables": { "file": null } }' -F map='{ "0": ["variables.file"] }' -F 0=@path/to/your_file.jpg http://localhost:4000/uploads
- 通过 POSTman 发送查询请求
打开 POSTman,创建一个新的 POST 请求,并在 header 中添加 content-type 为 multipart/form-data。然后,在 body 中选择文件选项,选择要上传的文件并发送请求。
结论
总之,在本文中,我们深入了解了如何使用 @gutenye/apollo-upload-server 来开发更加灵活的 GraphQL 应用。我们了解了如何使用 multer 模块上传图像,并将其发送到 GraphQL 服务中。此外,我们还探讨了如何在 Resolver 中处理上传的图像,并且将其存储到多部分表单数据中。
复杂的项目中,你可以通过设置适当的存储策略来优化代码,将文件存储在内存中,而不是磁盘上,以提高性能等。
希望本文对你有所帮助!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/60055a9881e8991b448d8139