Nodejs、GraphQL、MongoDB、Hapi 和 Swagger 构建 API(四)

简介: 笔记

7.png可重用 API 流行的最大原因是 API 允许使用来自 Web 客户端、移动应用程序、桌面应用程序的数据,实际上是任何客户端。将构建一个基于 Nodejs,由 MongoDB 数据驱动的强大而灵活的 GraphQL API,并支持 Swagger 文档。

项目代码仓库:github.com/QuintionTan…

系列文章:


实施 GraphQL


8.png


GraphQL 究竟是什么?

GraphQL 的力量来自一个简单的想法,不是在服务器上定义响应的结构,而是将灵活性赋予了客户端。每个请求都指定了它想要返回的字段和关系,而 GraphQL 将构建一个为这个特定请求量身定制的响应。好处:只需要一次往返即可获取所有可能跨越多个 REST 端点的复杂数据,同时只返回实际需要的数据,仅此而已。

GraphQL 解决了传统 REST API 可能面临的一些痛点,如:

  • 过度获取:响应中有不使用的数据。
  • 取材不足:没有足够的数据来调用端点,导致需要调用第二个端点。

在这两种情况下,它们都可能带来性能问题:要么使用比理想情况更多的带宽,要么发出比理想情况更多的 HTTP 请求。

在一个完美的世界里,这些问题永远不会出现;将拥有完全正确的端点来为产品提供完全正确的数据。

当扩展和迭代产品时,经常会出现这些问题。在页面上使用的数据经常发生变化,并且为每个组件维护一个具有完全正确数据的单独端点的成本变得过高。

因此,最终会在没有太多端点和让端点最适合每个组件的需求之间做出折衷。这将导致在某些情况下过度获取(端点将提供比一个特定组件所需的数据更多的数据),并在其他一些情况下导致获取不足(将需要调用第二个端点)。

开始使用 GraphQL

首先,需要安装相应的依赖项。


yarn add graphql apollo-server-hapi

Graphql 是 graphql 的主要包,apollo-server-hapi 是 Hapi 服务器和 GraphQL 之间的粘合剂。

让项目根目录下创建一个名新的件夹 graphql,并在其目录下创建文件 PaintingType.js,代码如下:

const graphql = require("graphql");
const { GraphQLObjectType, GraphQLString } = graphql;
const PaintingType = new GraphQLObjectType({
    name: "Painting",
    fields: () => ({
        id: { type: GraphQLString },
        name: { type: GraphQLString },
        url: { type: GraphQLString },
        techniques: { type: GraphQLString },
    }),
});
module.exports = PaintingType;

代码创建了一个新的 GraphQLObjectType,定义的几乎所有 GraphQL 类型都是对象类型。对象类型有一个名称,但最重要的是描述它们的字段。GraphQL 是一种静态类型语言,这意味着必须为字段声明类型,代码中声明了所有字段类型都是 GraphQLString

现在需要为创建的 PaintingType 提供查询操作,在目录 graphql 创建文件 schema.js,代码如下:

const graphql = require("graphql");
const PaintingType = require("./PaintingType");
const { GraphQLObjectType, GraphQLString, GraphQLSchema } = graphql;
const Painting = require("./../models/Painting");
const RootQuery = new GraphQLObjectType({
    name: "RootQuery",
    fields: {
        painting: {
            type: PaintingType,
            args: { id: { type: GraphQLString } },
            resolve(parent, args) {
                // 保存数据逻辑
                return Painting.findById(args.id);
            },
        },
    },
});
module.exports = new GraphQLSchema({
    query: RootQuery,
});

上述代码将提供给服务器的根查询,字段部分现在更加复杂了,正在传递带有类型 PaintingTypeargs 字段的字段名称。那么如何找到一条 painting 特定的记录,需要某种参数来排序,在这种情况下,通常是 id

接下来,resolve 是带有两个参数的函数,parent 以及 args

只是为了说明,GraphQL 查询如下所示:

{
    painting(id:20){
        name
    }
}

painting 查询来自 PaintingType.js 如何传递一个参数,这是 resolve() 中的 args 参数,参数 parent 将用于更复杂的查询,在这些查询中有更多的嵌套。

接下来导出根查询并将其传递给 Hapi 服务器, GraphQLSchema 类型是传递给服务器的根查询/模式定义。

module.exports = new GraphQLSchema({
    query: RootQuery,
});

回到 server.js,增加 GraphQLschema.js 相关的逻辑。

const { graphiqlHapi, graphqlHapi } = require("apollo-server-hapi");
const schema = require("./graphql/schema");

接下来需要注册 hapi-graphql 插件,在 server.register({}) 中,传递了 GraphQL 配置。

await server.register({
    plugin: graphiqlHapi,
    options: {
        path: "/graphiql",
        graphiqlOptions: {
            endpointURL: "/graphql",
        },
        route: {
            cors: true,
        },
    },
});

安装了 graphiql 插件,注意它是 graphiql 而不是 graphql。接下来让注册一个新插件:graphqlHapi,它包含之前制作的模式。

await server.register({
    plugin: graphqlHapi,
    options: {
        path: "/graphql",
        graphqlOptions: {
            schema,
        },
        route: {
            cors: true,
        },
    },
});

现在,打开浏览器,输入 http://localhost:3006/graphiql

接下来在左侧输入查询语句:

{
  painting(id:"63a433eed0f861feafa369d4"){
    name,
    url
  }
}

9.png

执行之后结果如图:

10.png

至此,GraphQL 已经添加到项目中了,后续需要根据最新的版本优化代码。



相关文章
|
2月前
|
人工智能 API 开发工具
构建AI智能体:一、初识AI大模型与API调用
本文介绍大模型基础知识及API调用方法,涵盖阿里云百炼平台密钥申请、DashScope SDK使用、Python调用示例(如文本情感分析、图像文字识别),助力开发者快速上手大模型应用开发。
1222 16
构建AI智能体:一、初识AI大模型与API调用
|
3月前
|
安全 Java API
使用 Java 构建强大的 REST API 的四个基本技巧
本文结合探险领域案例,分享Java构建REST API的四大核心策略:统一资源命名、版本控制与自动化文档、安全防护及标准化异常处理,助力开发者打造易用、可维护、安全可靠的稳健API服务。
230 2
|
4月前
|
运维 NoSQL Serverless
《第四纪元》玩得轻松,构建也轻松 | 阿里云云原生 API 网关、函数计算助力 IGame 快速构建轻休闲游戏
在轻休闲游戏流量波动大、生命周期短的背景下,传统架构难以应对成本与扩展挑战。本文介绍了基于阿里云函数计算 FC 和 Redis 构建的新一代服务器架构,实现弹性伸缩、成本优化与高效运维,助力轻休闲游戏快速迭代与稳定运营,提升开发效率并降低运维复杂度。
《第四纪元》玩得轻松,构建也轻松 | 阿里云云原生 API 网关、函数计算助力 IGame 快速构建轻休闲游戏
|
3月前
|
监控 安全 API
构建坚不可摧的防线:全方位保障API接口数据安全
在数字化时代,API作为系统间数据沟通的桥梁,其安全性至关重要。本文系统解析API安全的四大基石:身份认证、授权管理、数据完整性与机密性,并深入探讨HTTPS加密、强认证机制、精细授权、数据保护及纵深防御等关键技术实践,帮助企业构建全面的API安全体系,防范数据泄露与攻击风险,保障数据传输安全与业务稳定运行。
|
5月前
|
NoSQL MongoDB 数据库
数据库数据恢复—MongoDB数据库数据恢复案例
MongoDB数据库数据恢复环境: 一台操作系统为Windows Server的虚拟机上部署MongoDB数据库。 MongoDB数据库故障: 工作人员在MongoDB服务仍然开启的情况下将MongoDB数据库文件拷贝到其他分区,数据复制完成后将MongoDB数据库原先所在的分区进行了格式化操作。 结果发现拷贝过去的数据无法使用。管理员又将数据拷贝回原始分区,MongoDB服务仍然无法使用,报错“Windows无法启动MongoDB服务(位于 本地计算机 上)错误1067:进程意外终止。”
|
5月前
|
缓存 NoSQL Linux
在CentOS 7系统中彻底移除MongoDB数据库的步骤
以上步骤完成后,MongoDB应该会从您的CentOS 7系统中被彻底移除。在执行上述操作前,请确保已经备份好所有重要数据以防丢失。这些步骤操作需要一些基本的Linux系统管理知识,若您对某一步骤不是非常清楚,请先进行必要的学习或咨询专业人士。在执行系统级操作时,推荐在实施前创建系统快照或备份,以便在出现问题时能够恢复到原先的状态。
459 79
|
5月前
|
存储 NoSQL MongoDB
MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
279 8
MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
|
4月前
|
运维 NoSQL 容灾
告别运维噩梦:手把手教你将自建 MongoDB 平滑迁移至云数据库
程序员为何逃离自建MongoDB?扩容困难、运维复杂、高可用性差成痛点。阿里云MongoDB提供分钟级扩容、自动诊断与高可用保障,助力企业高效运维、降本增效,实现数据库“无感运维”。
|
8月前
|
NoSQL MongoDB 数据库
数据库数据恢复——MongoDB数据库服务无法启动的数据恢复案例
MongoDB数据库数据恢复环境: 一台Windows Server操作系统虚拟机上部署MongoDB数据库。 MongoDB数据库故障: 管理员在未关闭MongoDB服务的情况下拷贝数据库文件。将MongoDB数据库文件拷贝到其他分区后,对MongoDB数据库所在原分区进行了格式化操作。格式化完成后将数据库文件拷回原分区,并重新启动MongoDB服务。发现服务无法启动并报错。
|
10月前
|
存储 NoSQL MongoDB
数据库数据恢复—MongoDB数据库迁移过程中丢失文件的数据恢复案例
某单位一台MongoDB数据库由于业务需求进行了数据迁移,数据库迁移后提示:“Windows无法启动MongoDB服务(位于 本地计算机 上)错误1067:进程意外终止。”

推荐镜像

更多