GraphQL 是一种查询语言和运行时环境,用于管理 API 中的数据。GraphQL 的优点在于有着强大的类型系统和灵活的查询语言,允许客户端只请求所需的数据,避免了 REST API 中过度获取数据的问题。
然而,GraphQL 难以处理文件上传和下载这类操作,因为文件通常需要使用 multipart/form-data 格式进行传输,而不是像 JSON 和 GraphQL 查询一样的普通格式。
在本文中,我们将学习如何在 GraphQL 中实现文件上传和下载的功能,并提供一些示例代码供参考。
文件上传
在 GraphQL 中处理文件上传的方法主要有两种:一是基于 Multipart/form-data 格式的传输;二是使用 Base64 编码字符串的方式。
Multipart/form-data 格式
在使用 Multipart/form-data 格式进行文件上传时,客户端需要将数据打包为多部分的形式发送给服务端。每个部分都必须带有 Content-Disposition 首部指定其类型和名称。服务端需要根据 Content-Disposition 处理上传文件的部分。
以下是一个示例的 GraphQL 查询:
mutation UploadFile($file: Upload!) { uploadFile(input: { file: $file }) { id filename mimetype } }
其中,文件上传参数 file
声明为 Upload
类型。
在客户端,可以使用 FormData
对象构建表单,将需要上传的文件添加到其中,并将其作为 fetch
方法的第二个参数传递。
以下是一个使用了 FormData
的示例代码:
-- -------------------- ---- ------- ----- ----- - --------------------------------------- ----- ---- - --- ----------- ------------------------- ---------------- ------ - -------- ----------------- -------- - ----------------- - ----- ----- -- - -- -------- -------- - - -- ---------- - ----- ----- -- ---- ------------------ ---------------- ---- ------------------ ---- ---------------- ---------------- ----------------- - ------- ------- ----- ----- ----------- -- --------------------- -- -------------------
在服务端,需要使用 graphql-upload
这个中间件来承载上传的文件。以下是使用 graphql-upload
的示例:
-- -------------------- ---- ------- ----- - ------------- --- - - --------------------------------- ----- ------- - ------------------- ----- - ----------------- - - -------------- ----- - -------------------- - - -------------------------- ----- -------- - ---- ------ ------ ---- ---- - --- --- --------- ------- --------- ------- - ---- -------- - ----------------- --------- ----- - -- ----- --------- - - --------- - ----------- ----- --- - ----- -- -- - ----- - ----------------- --------- -------- - - ----- ------ ----- ------ - ------------------- ----- ---- - - --- ---------- --------- -------- -- ----- ---- - -------------------------------- ----- --- --------------- -- ------------------------------------------------ ---------- ------ ----- -- -- -- ----- ------ - --- -------------- --------- ---------- --- ----- --- - ---------- ------------------------------ ------------ --------- --------- -- ---- ------------------------ --- --- ---------------- -- -- ------------------- ------- -- -------------------------
Base64 编码
在使用 Base64 编码上传文件时,客户端需要将文件数据转换为一个 Base64 编码的字符串,然后将其包含在 GraphQL 查询中。服务端需要将 Base64 解码后处理上传的文件。
以下是一个使用 Base64 编码上传文件的示例:
mutation UploadFile($file: String!) { uploadFile(input: { file: $file }) { id filename mimetype } }
上传参数 file
声明为 String
类型。
在客户端,可以使用 FileReader
对象读取文件数据,将其转换为 Base64 编码的字符串,并将其作为 GraphQL 查询中文件参数的占位符。
以下是一个使用了 FileReader
的示例代码:
-- -------------------- ---- ------- ----- ----- - --------------------------------------- ----- ------ - --- ------------- ------------------------------- -- -- - ----- ---- - ---------------------------------------------- - --- ----------------- - ------- ------- -------- - --------------- ------------------ -- ----- ---------------- ------ - -------- ----------------- -------- - ----------------- - ----- ----- -- - -- -------- -------- - - -- ---------- - ----- ---- -- --- ----------- -- --------------------- -- ------------------- --- -------------------------------------
在服务端,需要在代码中解码 Base64 编码的文件数据,如下所示:
-- -------------------- ---- ------- ----- - ------------- --- - - --------------------------------- ----- ------- - ------------------- ----- - ----------------- - - -------------- ----- - ---- - - ---------------- ----- -------- - ---- ---- ---- - --- --- --------- ------- --------- ------- - ---- -------- - ----------------- --------- ----- - -- ----- --------- - - --------- - ----------- ----- --- - ----- -- -- - ----- --- - ------------------ ---------- ----- -------- - ------- - ----------------------- - --- - ------------ ------------------- ----- -- - ------------------------ ----- ---- - - --- --------- --------- -------------------------- -- ----- ---- - --------------- -------- --------- ----- --- --------------- -- --------------------------------------------- ---------- ------ ----- -- -- -- ----- ------ - --- -------------- --------- ---------- --- ----- --- - ---------- ------------------------ --- --- ---------------- -- -- ------------------- ------- -- -------------------------
文件下载
在 GraphQL 中实现文件下载通常需要借助于 HTTP 响应,服务端需要将文件数据作为响应数据发送给客户端。React-Native 和 React DOM 支持使用 URL.createObjectURL() 方法将响应转化为本地 url。
以下是一个使用 GraphQL 下载文件的示例:
query DownloadFile($id: ID!) { downloadFile(id: $id) }
其中,查询参数 id
指定要下载的文件的 ID。
在服务端,需要通过 ID 查询文件数据,并将其作为响应数据重定向到需要下载该文件的页面。
以下是一个使用了 express
的示例代码:
-- -------------------- ---- ------- ----- - ---- - - ---------------- ----- ------- - ------------------- ----- --- - ---------- ------------------------ ----- ---- -- - ----- ---- - --------------- -------- --------------- ------------------- --- ---------------- -- -- ------------------- ------- -- -------------------------
在客户端,我们需要发送一个 HTTP 请求到服务端,然后使用传统的下载方式来下载文件。
以下是一个使用了 fetch
的示例代码:
-- -------------------- ---- ------- ----- ------------ - ----- ---- --------- -- - ----- --- - ----- ------------------------- ----- --- - ----- --- --------------- -- - ----- ---- - ----------- ----- --------- - -------------------------- ------------------- --- ----- ---- - ---------------------------- --------- - ---- ----------------------------- ---------- ------------- --
结论
通过本文的学习,我们了解到了如何在 GraphQL 中实现文件的上传和下载功能。在上传文件时,我们需要借助于 graphql-upload
中间件来处理请求体,支持用户使用 multipart/form-data 格式进行文件上传和处理。在下载文件时,我们需要依赖于服务端的 HTTP 响应和客户端的传统下载方式。这些方法为在 GraphQL 中使用文件提供了强大的基础。
希望本文能为您在 GraphQL 开发中的文件操作提供有益的指导和启示。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6721c8352e7021665e08bce3