如何在 Fastify 中使用 GraphQL

前言

随着现代web应用程序的不断发展,单一页面应用程序(SPA)的流行与日俱增。随之而来的是越来越多的客户端的请求和服务端的响应。GraphQL使得(在客户端和服务器之间)请求和响应的交互更加顺畅。GraphQL是一种API查询语言和运行时,旨在优化API的性能和灵活性。

Fastify是Node.js的快速和低开销的Web框架。Fastify和它的生态系统中的插件可以帮助我们快速构建GraphQL服务端。

在本文中,我们将了解如何在Fastify中使用GraphQL,从GraphQL API的基础知识开始,了解现代,设置开发环境,最后是MySQL数据库使用GraphQL的示例。

GraphQL基础知识

GraphQL使用新的查询语言来定义API的查询能力,并使用类型系统来定义数据的结构。查询语言称为GraphQL查询语言(GQL)。查询语言可用于以下多种类型的操作:

  • 获取某些数据
  • 更改现有数据
  • 订阅发生的事件

查询是由服务器解决的操作。数据本质上是一组关联对象,这些对象由字段组成。查询图是字段关系的图形表示。查询图同时决定了查询方法。每个字段可以是标量或由再次嵌套查询图形以形成复杂查询。这是在GraphQL中定义一个查询:

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

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

在这个示例中,查询字段的名称是人(human),并包含一个参数id,该参数用于指定对哪些人进行查询。将返回名称,年龄和标识符(id)作为输出。

使用GraphQL语言的极度灵活性,可以更轻松地进行改进和扩展。在GraphQL中,使用批处理技术,可以缩短取回时间并最小化网络连​​接。

但是,在许多情况下,浏览器不会直接执行查询,而是使用某种具体执行器(例如,Apollo Client)代表用户与服务器交互。

准备工作

在开始使用GraphQL之前,需要安装和启动环境。请查看以下内容:

  • Node.js
  • NPM 包管理器
  • MySQL 数据库

要了解更多信息,请访问官方网站。

创建项目

首先,我们需要创建一个新的Node.js项目。在命令行中打开新的项目目录并运行:

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

进入项目根目录后,我们将安装Fastify和Fastify插件,以及GraphQL和相关插件:

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

Fastify插件

  • fastify-autoload:自动加载路由和hooks.
  • fastify-cors:跨域资源共享
  • fastify-helmet:安全中间件
  • fastify-static:静态文件服务
  • fastify-gql:把GraphQL集成到Fastify中去
  • apollo-server-fastify:GraphQL服务的路由插件,精简的GraphQL HTTP服务器

GraphQL相关插件

  • graphql:graphql JavaScript库
  • apollo-server-fastify和fastify-gql:将GraphQL和Fastify集成

使用Fastify和GraphQL的复杂示例

接下来,我们将创建一个从MySQL数据库检索数据并使用GraphQL API公开的示例。

数据库配置

应用程序将使用MySQL作为其数据库。安装并运行MySQL,然后使用以下命令来创建数据库,并为其添加一些数据。

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

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

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

设置fastify

我们将创建一个名为index.js的新文件,其中将启动Fastify:

---- -------

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

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

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

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

在这个示例中,我们将Fastify与中间件、静态文件服务和自动加载路由的开箱即用支持集成。请注意,我们使用3000端口运行Fastify并暴露公共IP地址。

集成的GraphQL和MySQL

要集成GraphQL和MySQL,我们将创建一个名为schema.js的新文件,这样它就可以捆绑到我们的Fastify应用程序中。schema.js将定义我们的GraphQL数据类型和相应的解析器:

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

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

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

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

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

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

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

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

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

在这个示例中,我们定义了GraphQL查询体的各个类型。并从我们的MySQL承载主机访问数据(实际示例的查询 -

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

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

---- -----

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

'use strict';

const { ApolloServer } = require('apollo-server-fastify'); const { taskDefs, resolvers } = require('./schema'); const mysql = require('mysql2/promise');

module.exports = async (fastify) => { // Initialize our database client const db = await mysql.createConnection({ host: "localhost", user: "root", password: "password", database: "fastify_graphql" }); // Attach our connection to fastify too fastify.decorate('db', db);

// Install GraphQL interface const server = new ApolloServer({ typeDefs: taskDefs, resolvers, });

// Decorate Fastify with GraphQL facilities fastify.register(server.createHandler()); }

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

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

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

'use strict';

module.exports = async function (fastify, opts) { fastify.get('/api/tasks', async function (req, res) { const query = "
SELECT
id,
title,
description,
is_completed,
created_at
FROM
tasks
";

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

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

})

fastify.get('/api/toggle', async function (req, res) { const { id } = req.query;

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

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

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

}) }

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

'use strict';

const graphqlSchema = require('../graphql/schema');

module.exports = async function (fastify, opts) { // GraphQL related routes fastify.register(async function (app) { app.register(require("fastify-gql"), { schema: graphqlSchema.taskDefs, resolvers: graphqlSchema.resolvers, graphiql: true }); }, { prefix: '/graphql' }) }

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

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

'use strict';

const fastify = require('fastify')({ logger: true })

fastify.register(require('fastify-cors')) fastify.register(require('fastify-helmet')) fastify.register(require('fastify-static'), { root: __dirname, prefix: '/public/', }) fastify.register(require('fastify-autoload'), { dir: './routes', })

fastify.register(require('./graphql'), { prefix: '/v1' })

fastify.listen(3000, '0.0.0.0', (err) => { if (err) { console.error(err) process.exit(1) } })

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

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

query { task(id:1) { title description is_completed created_at } }

---------

{ "data": { "task": { "title": "Learn GraphQL", "description": "Study GraphQL in depth, the future of API management", "is_completed": 1, "created_at": "Sun May 23 2021 22:05:06 GMT+0800 (China Standard Time)" } } }

-- --

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

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

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

猜你喜欢

  • 如何使用 React 进行无障碍开发

    React 是一种流行的前端开发框架,但不是所有人都能轻松地使用它。对于盲人或视力障碍者等用户来说,React 网站可能无法提供易于导航和使用的体验。因此,为了让您的网站对所有用户都更友好,本文将介绍...

    8 天前
  • 在使用 SSE 时如何处理客户端断电的情况?

    SSE(Server-Sent Events)是一种服务器推送技术,能够让服务器实时地将数据发送到客户端,而不需要客户端不断地向服务器请求。这种技术在现代 Web 应用中越来越常见,因为它可以降低网络...

    8 天前
  • Material Design 中 SnackBar 的实现方法及注意事项

    Material Design 中 SnackBar 的实现方法及注意事项 介绍 SnackBar 是一种 Material Design 风格的 Alert(提示)控件,它显示在屏幕的底部,并提供简...

    8 天前
  • Redux-thunk 详解及应用场景剖析

    在前端开发中,Redux 是一种很受欢迎的状态管理库,它可以有效地管理应用程序中的状态。然而,在某些情况下,Redux 还需要配合一些中间件才能实现更强大的功能。其中最常用的中间件之一就是 Redux...

    8 天前
  • 优化 C# 应用程序性能

    介绍 C# 是一种被广泛使用的面向对象编程语言,被用于开发各种类型的应用程序。然而,C# 应用程序可能会遇到性能瓶颈,特别是在复杂的代码中。在本文中,我们将探讨如何优化 C# 应用程序性能以提高应用程...

    8 天前
  • 几个不用依赖包的 webpack 实战问题

    随着前端项目的日益复杂,webpack成为了前端必备的构建工具之一。但是,大多数教程和文章都使用了诸如webpack-dev-server和其他类似的依赖包来讲解webpack的使用方法,这样会使新手...

    8 天前
  • 使用 Next.js 生成静态站点提高 SEO 优化

    随着搜索引擎的普及和用户对网页速度和体验的需求增加,SEO 优化变得越来越重要。作为前端开发者,我们可以通过使用 Next.js 框架来生成静态站点,提高网站的 SEO 优化。

    8 天前
  • PM2 遇到 "Error: Cannot find module" 问题的解决方案

    背景 在使用 PM2 管理 Node.js 应用程序时,我们可能会遇到以下错误信息: ------ ------ ---- ------ -----------------这种报错信息通常出现在程序在...

    8 天前
  • Kubernetes 中使用 Elasticsearch 进行日志集中

    前言 随着云计算、容器技术、微服务架构的发展,现代应用程序已经变得越来越复杂,其中的组件也越来越多。作为开发人员或者运维人员,需要能够追踪并分析应用程序中的日志信息,以便确定错误发生的地点,并快速解决...

    8 天前
  • ECMAScript 2021:了解 null 和 undefined 的区别及使用方法

    在 JavaScript 中,null 和 undefined 都表示没有值,但它们之间存在一些区别。在本文中,我们将深入探讨 null 和 undefined 的区别,并介绍它们的使用方法。

    8 天前
  • 前端Angular与GraphQL结合的使用技巧

    前言 随着前端框架的不断演进和GraphQL的出现,前端与后端之间的数据交互变得更加灵活和高效。Angular是一款强大的前端JS框架,而GraphQL是一个用于API的查询语言。

    8 天前
  • Mocha 测试框架中使用 should.js 的方法简介

    前言 Mocha 是一个流行的 JavaScript 测试框架,它在前端及后端应用程序开发中得到广泛应用。should.js 是一个类似于断言库的库,它可增加我们编写测试用例的可读性和可靠性。

    8 天前
  • ES9 中 Promise.prototype.finally() 方法的使用技巧

    随着 JavaScript 前端技术的不断发展,Promise 已成为前端开发中常用的异步编程解决方案之一。ES9 中,Promise.prototype.finally() 方法被引入,为 Prom...

    8 天前
  • React Native 的优缺点:从开发者视角看

    在移动开发领域,React Native 受到了越来越多的关注和运用。在这篇文章中,我们将从开发者的角度探讨 React Native 的优缺点,以及为什么它在移动应用开发中备受推崇。

    8 天前
  • TypeScript 的多种数据类型:如何处理任意数据类型

    在前端开发中,必不可少的是对数据类型的处理。TypeScript 作为一种静态类型的语言,为我们提供了更多的数据类型,并且让我们可以更加安全和有效地处理数据。在本文中,我们将详细介绍 TypeScri...

    8 天前
  • CSS Reset 的优化策略与方法

    在进行前端网页开发时,我们常常会遇到浏览器兼容性的问题,尤其在 CSS 样式方面。而 CSS Reset 可以帮助开发者重置浏览器的默认样式,从而避免这些兼容性问题。

    8 天前
  • webpack-dev-server 使用方法及13个小技巧

    前言 随着前端技术的不断发展,前端项目的复杂度也越来越高,为了提高项目开发的效率及便捷性,一些工具和框架被广泛应用于前端开发中。其中,Webpack 是目前前端领域中使用最广的打包工具之一,许多前端项...

    8 天前
  • 如何优化 Web Components 中的性能瓶颈

    如何优化 Web Components 中的性能瓶颈 Web Components 是一种新兴的技术,它是一个自定义元素,可以在 HTML 中被声明和使用。Web Components 由 4 个不同...

    8 天前
  • 从 Promise.any、Promise.allSettled 到 Nullish Coalescing:ES11 新增的快捷操作让代码更简洁

    从Promise.any、Promise.allSettled到Nullish Coalescing:ES11新增的快捷操作让代码更简洁 随着JavaScript的发展,JavaScript语言也不断...

    8 天前
  • 在 Kubernetes 中使用服务质量 (QoS) 调整容器资源

    Kubernetes 是一个开源的容器编排系统,可轻松部署和管理 Docker 容器。在 Kubernetes 中,可以通过服务质量 (QoS) 设置来调整容器资源,以确保应用程序正常运行并提高系统性...

    8 天前

相关推荐

    暂无文章