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

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 笔记

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 已经添加到项目中了,后续需要根据最新的版本优化代码。



相关文章
|
5月前
|
XML JSON API
如何从 Swagger 导出 API 文档
Swagger 使这项任务相对简单,允许开发者以各种格式(如 JSON 和 YAML)导出 API 文档。在这篇博文中,我们将详细探讨如何从 Swagger 导出 API 文档。
如何从 Swagger 导出 API 文档
|
5月前
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
6月前
|
Kubernetes API 网络安全
当node节点kubectl 命令无法连接到 Kubernetes API 服务器
当Node节点上的 `kubectl`无法连接到Kubernetes API服务器时,可以通过以上步骤逐步排查和解决问题。首先确保网络连接正常,验证 `kubeconfig`文件配置正确,检查API服务器和Node节点的状态,最后排除防火墙或网络策略的干扰,并通过重启服务恢复正常连接。通过这些措施,可以有效解决与Kubernetes API服务器通信的常见问题,从而保障集群的正常运行。
418 17
|
10月前
|
JSON 缓存 JavaScript
深入浅出:使用Node.js构建RESTful API
在这个数字时代,API已成为软件开发的基石之一。本文旨在引导初学者通过Node.js和Express框架快速搭建一个功能完备的RESTful API。我们将从零开始,逐步深入,不仅涉及代码编写,还包括设计原则、最佳实践及调试技巧。无论你是初探后端开发,还是希望扩展你的技术栈,这篇文章都将是你的理想指南。
|
8月前
|
存储 NoSQL JavaScript
Node.js导入MongoDB具体操作指南
通过本文,您已经学会了如何在Node.js中导入MongoDB并执行基本的CRUD操作。Node.js与MongoDB的结合使得构建高效、可扩展的后端服务变得更加容易。通过遵循本文的步骤,您可以快速设置并运行一个强大的数据存储和处理系统。希望这篇指南能为您的开发工作提供实用的帮助。
206 13
|
9月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
197 12
|
10月前
|
Java 测试技术 API
详解Swagger:Spring Boot中的API文档生成与测试工具
详解Swagger:Spring Boot中的API文档生成与测试工具
691 4
|
10月前
|
JavaScript NoSQL API
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发如同一座灯塔,指引着数据的海洋。本文将带你航行在Node.js的海域,探索如何从一张白纸到完成一个功能完备的RESTful API。我们将一起学习如何搭建开发环境、设计API结构、处理数据请求与响应,以及实现数据库交互。准备好了吗?启航吧!
|
10月前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
2月前
|
NoSQL MongoDB 数据库
数据库数据恢复—MongoDB数据库数据恢复案例
MongoDB数据库数据恢复环境: 一台操作系统为Windows Server的虚拟机上部署MongoDB数据库。 MongoDB数据库故障: 工作人员在MongoDB服务仍然开启的情况下将MongoDB数据库文件拷贝到其他分区,数据复制完成后将MongoDB数据库原先所在的分区进行了格式化操作。 结果发现拷贝过去的数据无法使用。管理员又将数据拷贝回原始分区,MongoDB服务仍然无法使用,报错“Windows无法启动MongoDB服务(位于 本地计算机 上)错误1067:进程意外终止。”

热门文章

最新文章

推荐镜像

更多