GraphQL 如何处理文件上传

GraphQL 是一个非常强大的 API 查询语言和运行时,它提供了强类型系统和批量数据查询等特性。GraphQL 同时也提供了扩展性强的语言扩展,让我们可以轻松地在其语言体系内添加我们自己需要的功能。

在实际的应用开发中,上传文件是非常常见的操作。但是,由于 HTTP 协议的限制,文件上传是一个相对复杂的过程,通常需要以 multipart/form-data 的形式传递二进制数据。本文将重点介绍 GraphQL 如何处理文件上传。

传统的文件上传方式

在传统 Web 开发中,文件上传通常使用 form 标签配合 input[type=file] 标签实现。用户完成选择文件之后,提交表单请求。服务器接收到请求之后,会读取用户上传的文件内容,并将其保存到本地磁盘上。在处理文件上传过程中,我们通常需要了解以下几个问题:

  1. 上传文件的大小和类型是否合法;
  2. 如何读取上传的二进制数据;
  3. 如何保存上传的文件;
  4. 如何进行文件校验和处理异常。

GraphQL 文件上传

与传统的文件上传不同,GraphQL 应用程序通常会使用 JSON 作为请求和响应的格式。但是,JSON 格式并不支持二进制数据的直接传输。那么,如何在 GraphQL 中上传文件呢?

GraphQL 的文件上传依赖于 multipart/form-data 数据格式。在上传文件时,我们需要将 GraphQL 查询和变量一起打包进 multipart/form-data 格式中。同时,文件数据也必须嵌入到 multipart/form-data 格式的数据包中。

运行环境和依赖库

为了运行本文中提到的代码示例,你需要先安装以下环境和依赖库:

  • Node.js 环境
  • Express Web 服务
  • graphql-multipart-request-spec 中间件库
  • GraphQL Yoga 库(或其他的 GraphQL 实现)

服务器端代码

以下是一个简单的 GraphQL 文件上传的示例代码:

----- ------- - -------------------
----- - -------------- -------------------- - - --------------------------
----- - ------------- --- - - ---------------------------------

----- -------- - ----
  ------ ------

  ---- ----- -
    ------ -------
  -

  ---- -------- -
    ------------------ --------- -------
  -
--

----- --------- - -
  ------- --------------

  ------ -
    ------ -- -- ------ ---- ----------
  --

  --------- -
    ------------- ----- -------- ----- -- -
      ----- - ----------------- --------- --------- -------- - - ----- ----------

      -- -- --------- ---- --- ---- ------- ---- -- ------ -- -- --- ---- ------ -- --

      ------ ----- ------ ---------- -------------
    --
  --
--

----- ------ - --- --------------
  ---------
  ----------
---

----- --- - ----------

--------------------------------

------------------------ --- ---

------------ ----- ---- -- -- --
  --------------- ------ ----- -- --------------------------------------------
--

在上面的示例代码中,我们引入了两个 GraphQL 相关的库,分别是 graphql-uploadapollo-server-express。其中:

  • graphql-upload 库提供了我们需要使用的 GraphQLUpload scalar 类型;
  • apollo-server-express 库提供了我们需要用到的 ApolloServergql 对象。

在类型定义中,我们声明了 Upload 标量类型,并定义了一个名为 singleUpload 的 mutation。

在解析器中,我们将 Upload 标量类型与 graphql-upload 库提供的 GraphQLUpload scalar 类型绑定起来。

singleUpload 中,我们通过解构 args.file(由 graphql-multipart-request-spec 中间件生成的 Upload 对象)获取到上传的文件流、文件名、MIME 类型和编码等信息,并进行处理。具体处理方法可以根据用户自己的需要进行设置。

客户端代码

以下是一个文件上传的 GraphQL 客户端示例代码:

------ - ------------- -------------- --- - ---- -----------------
------ - ---------------- - ---- -----------------------

----- ------ - --- --------------
  ----- ------------------
    ---- --------------------------------
  ---
  ------ --- ----------------
---

----- -------------------- - ----
  -------- ------------------- -------- -
    ------------------ ------
  -
--

-- ---- ---------------- ------------
----------------------------------------------------------------------- ----- --- -- -
  ----- ---- - ------------------

  -- -------- -------- ----- ------- ----- ------------------- ----
  ----- ---- - --- -----------
  ------------------------- ---------------- ------ --------------------- ---------- - ----- ---- - ----
  ------------------ ---------------- ---- ------------------ ----
  ---------------- ----- -----------

  --- -
    ----- ------ - ----- ---------------
      --------- ---------------------
      ---------- - ---- --
      -------- - ------------- - ------- ------- ----- ---- - --
    ---

    -------------------------
  - ----- ----- -
    -------------------
  -
---

在上面的代码中,我们使用了 createUploadLink 函数,将 GraphQL 客户端连接到了 GraphQL 服务器。通过创建监听 change 事件的文件选择器,我们可以获取用户选择的文件,并使用 FormData 对象将其打包成 multipart/form-data 格式。

在客户端的 mutate 函数中,我们使用 fetchOptions 参数来指定给服务器的请求选项,其中包括了 methodbody 两个属性。使用 FormData 打包数据之后,我们可以将其直接传递给 fetchOptions.body 属性。

总结

通过上述示例代码,我们了解到了 GraphQL 如何支持文件上传功能。通过将 GraphQL 查询和变量打包为 multipart/form-data 数据格式,我们可以直接向服务器发送二进制数据。和传统的文件上传方式相比,GraphQL 的文件上传借助于 JSON 和 multipart/form-data 数据格式而更加灵活和高效。

在实际的文件上传操作中,我们通常需要根据具体应用场景,调整服务器端的上传处理逻辑,并处理异常情况。同时,我们也需要合理地配置客户端与服务端之间的传输协议,以提高文件上传的效率和安全性。

如果你在实践过程中遇到了其他问题或觉得本文有待改进,请随时联系作者或在评论区留言。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/6465eb85968c7c53b0694f52


猜你喜欢

  • Enzyme 测试 React 组件:手把手教你入门

    Enzyme 测试 React 组件:手把手教你入门 前言 随着 React 技术的越来越普及,React 组件的可测试性变得越来越重要。而 Enzyme 就是一款很好用的测试 React 组件的库。

    1 年前
  • 如何在 Deno 中使用 WebSocket

    在现代 web 应用程序的开发过程中,WebSocket 已经成为了一个必不可少的工具。WebSocket 可以指定一个长时间的持久连接,以便客户端和服务器之间可以进行实时通信,从而避免了传统的轮询方...

    1 年前
  • 内鬼 Hapi.js + React.js 配合写的 SPA 之痛苦!

    前端开发中,尤其是在单页应用程序(SPA)的开发中,组件化已经变成了一个流行的趋势。React.js 则是这个趋势中的重要一环,它被广泛使用,并且它的组件化设计使得它非常适合构建大型的,复杂的前端应用...

    1 年前
  • Serverless 的神秘之处

    本文将介绍 Serverless 的概念、应用场景、工作原理,以及如何搭建一个基于 Serverless 的应用程序。 什么是 Serverless Serverless 是一种全新的云计算架构,...

    1 年前
  • 在 React 项目中利用 ES12 的 WeakRef 类提升性能

    在前端开发中,React 是非常流行的框架。然而,当我们在处理大量数据时,页面的性能往往会受到影响。为此,我们可以利用 ES12 中的 WeakRef 类来解决这个问题。

    1 年前
  • Mongoose 如何进行数据的字段验证?

    在 Node.js 中,Mongoose 是一个非常流行的 MongoDB 数据库对象建模工具。它提供了一种优雅的方式来定义和操作数据模式,使得我们可以更加轻松地进行查询、更新、删除等操作。

    1 年前
  • 如何在 SASS 中使用 BEM 命名规范进行样式开发

    在前端开发过程中,CSS 的样式开发一直是一个棘手的问题。为了让样式更加可维护和可重用,我们需要使用一种自然易懂的命名规范来编写 CSS 样式。BEM(Block Element Modifier)命...

    1 年前
  • Redux 优化实践:Immutable.js 与 reselect 库的结合使用

    简介 Redux 是一个可预测的 JavaScript 状态容器,它提供了可预测的状态管理和可维护的、可测试的代码结构。但是,Redux 的数据不是不可变的,这就使得 Redux 对于大规模数据集合的...

    1 年前
  • RESTful API 如何进行版本控制

    在前端开发中,RESTful API 是非常重要的一部分,它使得我们可以与后端服务器进行数据交互。但是,在开发过程中,RESTful API 的更新可能会对前端应用产生影响,因此,版本控制就变得非常重...

    1 年前
  • 使用 Socket.IO 构建多人游戏平台的指南

    前言 在互联网时代,网络游戏成为了人们日常娱乐生活的一部分。而多人在线游戏(MMOG)则更是以其交互、社交性等特点,吸引了大量的游戏玩家和开发者。 开发一款多人在线游戏,需要考虑的问题非常多,而网络通...

    1 年前
  • Angular 实例教程:从零到一打造企业级应用

    Angular 是一款流行的前端框架,它提供了许多强大的工具和库,使得开发者能够方便快捷地构建企业级应用。本文将介绍从零开始如何使用 Angular 构建一个完整的企业级应用,并着重讲解 Angula...

    1 年前
  • ES8 并发执行异步请求的最佳实践

    在现代的 Web 应用中,网络请求已经成为了一个无法避免的部分。而在处理网络请求的过程中,我们通常需要使用异步编程的方式来处理回调函数和异步数据。ES8 中引入了 async/await 关键字解决了...

    1 年前
  • 为什么在 gulp 中使用 LESS 总是失败?

    如果你是一个前端开发者,你可能已经听说过 LESS 这种流行的 CSS 预处理器。它提供了许多方便的功能,如变量、嵌套选择器和 mixins 等等,使得我们可以更轻松地编写样式表。

    1 年前
  • Sequelize 中的 HSTORE 字段类型详解

    在 PostgreSQL 数据库中,有一种特殊的数据类型叫做 HSTORE,它是一种键值对的映射结构,通常用于表示一些类似于配置信息的数据。在 Sequelize 中,我们可以很方便地使用 HSTOR...

    1 年前
  • Vue.js 的 slot 用法及注意事项

    在 Vue.js 组件中,slot 是非常强大和灵活的特性,可以让我们更方便地组合和复用组件,从而提高开发效率和代码可维护性。本文将介绍 Vue.js 中 slot 的用法和注意事项,并提供相关示例代...

    1 年前
  • Kubernetes 1.7.4 Release:让 Pod 逃生变得更快

    在 Kubernetes 1.7.4 的最新版本中,重要的安全和性能更新已经进行了发布。其中,最值得一提的是在 Pod 逃生方面的改进,使得应用程序更加可靠。下面是本文对 Kubernetes 1.7...

    1 年前
  • CSS Grid 中的 Flexbox

    在前端开发中,CSS Grid 和 Flexbox 都是常用的布局方式。CSS Grid 通过网格布局来实现高度灵活的布局,而 Flexbox 则主要用于实现一维布局,如垂直或水平方向上的布局。

    1 年前
  • PWA 技术在移动端应用中的集成解析

    在移动互联网时代下,移动应用开发变得越来越重要,用户对于应用性能和体验的要求也越来越高。而 PWA (Progressive Web Apps)技术便是一种新型的移动应用开发方式,可以帮助前端开发人员...

    1 年前
  • CSS Grid 如何实现媒体布局的变化

    在日常的网页设计中,我们常常需要根据不同的媒体设备尺寸来调整页面布局,以提供更好的用户体验。CSS Grid 是一种强大的布局工具,可以帮助我们快速实现响应式设计。

    1 年前
  • Express.js 中间件详解

    前言 Express.js 是一个基于 Node.js 平台的 Web 应用程序开发框架,由于其简单易用和高度可扩展性,已经成为前端开发工程师不可或缺的一部分。本篇文章将为您详细介绍 Express....

    1 年前

相关推荐

    暂无文章