使用Node.js构建API网关

使用Node.js构建API网关

当微服务架构中的服务被外部的客户端访问时,可以共享有关身份验证和传输的一些常见请求。API网关提供了一个共享层去处理服务协议之间的差异,同时满足特定客户端(像PC端浏览器,移动端设备和传统系统)的需求。

微服务和消费

微服务是一种面向服务的架构,团队可以独立设计,开发和发布他们的应用程序。它允许系统的各个层面的技术多样性,团队可以从最佳语言,数据库,协议和传输层中受益,以应对特定的技术挑战。例如,一个团队可以使用JSON over HTTP REST,而另一个团队可以使用gRPC over HTTP / 2或者像RabbitMQ这样的消息传递代理。

在某些情况下使用不同的数据序列化和协议可能很有用,但想要使用我们产品的客户可能有不同的要求。在具有同质技术堆栈的系统中也会出现问题,因为消费者可以从桌面浏览器到移动设备和主机游戏,再到传统系统。一个客户端可能期望XML格式(数据),而另一个客户端则需要JSON(JSON结构的数据)。在很多情况下,你需要同时支持。

当客户想要使用微服务时,你可能面临的另一个挑战来自于通用的共享逻辑,如身份验证,你应该不希望在所有服务中重新实现相同的功能吧。

总结一下:我们不希望在微服务架构中实现我们的内部服务,以支持多个客户端并重新实现相同的逻辑。这就是API网关出现的原因,并提供共享层来处理服务协议之间的差异并满足特定客户端的要求。

什么是API网关?

API网关是微服务体系结构中的一种服务,它为客户端提供与内部服务通信的共享层和API。API网关可以路由请求,转换协议,聚合数据实现共享逻辑,如身份验证和限速器。

你也可以将API网关视为我们微服务世界的入口。我们的系统可以有一个或多个API网关,具体取决于客户的要求。例如,我们可以为PC端浏览器,移动端应用和公共API设置单独的网关。

将API Gateway视为我们微服务世界的切入点

用于前端团队的Node.js API网关

由于API网关为浏览器等客户端应用程序提供了功能 - 它可以由负责前端应用程序的团队实现和管理。

这也意味着实现API网关的语言应该由负责特定客户端的团队选择。由于JavaScript是为浏览器开发应用程序的主要语言,即使你的微服务体系结构使用其他的语言进行开发,但是使用Node.js也不失为一个实现API网关的绝佳选择。

Netflix成功使用Node.js构建API网关及其Java后端来支持绝大部分的客户端 - 了解更多关于他们的方法的信息,请阅读Netflix的微服务--'已经铺好路'的平台既服务商业模式文章。

Netflix处理不同客户的方法,来源

API网关功能

我们在前面讨论过,你可以将通用共享逻辑放入你的API网关,而在本节将介绍最常见的网关职责(做什么)。

路由和版本控制

我们将API网关定义为微服务的入口。在你的网关服务中,你可以来自客户端的请求路由到特定服务。你甚至可以在路由期间处理版本控制或更改后端接口,而暴露在公共的接口可以保持不变。你还可以在API网关中定义与多个服务协作的新端点。

API网关作为微服务入口

演进式设计

API网关方法还可以帮助你分解你的整体应用。在大多数情况下,从头开始重写系统作为微服务不是一个好主意,也不可能,因为我们需要在转换过程中为业务提供功能。

在这种情况下,我们可以在整体应用前放置一个代理或API网关,实现微服务作为新功能,并将新端点路由到新服务,同时我们也可以通过巨型服务器为旧端点服务。之后,我们还可以将现有功能转移到新服务中,从而分解这个整体的应用。

通过演进式设计,我们可以从庞大的体系结构平滑过渡到微服务。

使用API​​网关的演化设计

身份认证

大多数微服务基础设施需要处理身份认证。将共享逻辑如身份验证添加到API网关可帮助你保持服务的小型化领域化

在微服务架构中,你可以通过网络配置将你的服务保护在DMZ (隔离区)中,并通过API网关将展示给客户端。该网关还可以处理多种身份验证方法。例如,你可以同时支持基于cookie令牌的身份验证。

带有认证的API网关

数据聚合

在微服务体系结构中,客户机可能需要不同聚合级别的数据,比如在各种微服务中进行数据实体的非规范化。在这种情况下,我们可以使用我们的API网关来解决这些依赖关系并从多个服务收集数据。

在下图中,你可以看到API网关如何将用户数据和信用数据合并作为一个数据返回给客户端。请注意,这些由不同的微服务拥有和管理。

序列化格式转换

可能发生的情况是,我们需要支持具有不同数据序列化格式要求的客户端。

想象一下我们的微服务使用JSON的情况,但我们的一个客户只能使用XML API。在这种情况下,我们可以将JSON转换为XML到API网关,而不是在所有微服务中实现。

协议转换

微服务体系结构允许多项协议传输并获得不同技术的好处。但是大多数客户端只支持一种协议。在这种情况下,我们需要为客户端转换服务协议。

API网关还可以处理客户端和微服务之间的协议转换。

在下一张图片中,你可以看到客户端期望通过HTTP REST进行的所有通信,而我们的内部微服务使用gRPC和GraphQL。

限速和缓存

在前面的例子中,你可以看到我们可以将通用的共享逻辑(如身份验证)放入API网关中。除了身份验证外,你还可以在API网关中实施速率限制,缓存和各种可靠性功能。

庞大的API网关

当你在实现的API网关时,你应该避免将非通用逻辑(如特定于域的数据转换)放到网关上。

服务应始终对其数据域拥有完全所有权。建立一个过于庞大的API网关需要服务团队操控,这违背了微服务的理念。

这就是为什么你应该小心在你的API网关中的数据聚合 - 它可以是强大的,但是你应该避免可能导致的特定于域的数据转换或规则处理逻辑。

始终为你的API网关定义明确的职责,并且只在其中包含通用共享逻辑。

Node.js API网关

虽然你希望在API网关中执行简单的操作,例如将请求路由到特定的服务,但你可以使用逆向代理(如nginx)。但是在某些时候,你可能需要实现一般代理不支​​持的逻辑。在这种情况下,你可以在Node.js中实现自己的 API网关。

在Node.js中,你可以使用http-proxy包简单地将请求代理到特定服务,或者你可以使用功能更多的功能丰富的express-gateway来创建API网关。

在我们的第一个API网关示例中,我们在将请求代理到用户服务之前对其进行身份验证。

const express = require('express')  
const httpProxy = require('express-http-proxy')  
const app = express()
const userServiceProxy = httpProxy('https://user-service')
// 身份验证
app.use((req, res, next) => {  
  // TODO: 身份验证逻辑代码
  next()
})
// 请求代理
app.get('/users/:userId', (req, res, next) => {  
  userServiceProxy(req, res, next)
})

另一种方法可以是在API网关中发出新请求,并将响应返回给客户端:

const express = require('express')  
const request = require('request-promise-native')  
const app = express()
// 处理: GET /users/me
app.get('/users/me', async (req, res) => {  
  const userId = req.session.userId
  const uri = `https://user-service/users/${userId}`
  const user = await request(uri)
  res.json(user)
})

总结了Node.js API网关

API网关提供了一个共享层,以满足微服务架构的客户需求。它有助于保持你的服务小而专注于领域。你可以将不同的通用逻辑添加到你的API网关,需要注意的是,你应该避免构建过于庞大的API网关,从而让服务团队获得控制权。

本文的版权归 ZRoger 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏匠心独运的博客

过来人的经验,谈谈一致性处理方案—分布式事务(DTS)

传统事务是使用数据库自身的事务属性(ACID),而数据库自身的事务属性是局限于当前实例,不能实现跨库。而对于大型分布式/微服务集群系统中,不仅存在着跨库的事务,...

47040
来自专栏腾讯NEXT学位

阅读前端项目源码的正确姿势!

18640
来自专栏Netkiller

压力测试中存在的问题

压力测试中存在的问题 (What) 什么是压力测试 软件压力测试是一种基本的质量保证行为,它是每个重要软件测试工作的一部分。软件压力测试的基本思路很简单: 不是...

34240
来自专栏开源优测

有那么几张图给大家看看

8410
来自专栏FH云彩

通过IP获取位置

21160
来自专栏hotqin888的专栏

MeritMS与Bentley Project Wise对比校审流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

21810
来自专栏小巫技术博客

App更新策略课程完结篇

13430
来自专栏云计算

微服务的模式 - 同步与异步

微服务是一种架构范例。在这种架构中,多个小型独立组件协同工作,从而构成一个系统。尽管它的操作复杂性较高,但这种范式已经被迅速采用。这是因为它有助于...

1.5K40
来自专栏杨建荣的学习笔记

运维平台中的脚本管理

截止目前,元数据的工作完成了一些阶段性的内容,当然还有非常多的需要细化的东西,从优先级层面来说,可以暂时放一放。 现在迫切需要的是一些能用起来的功能,比如结合业...

54450
来自专栏aCloudDeveloper

vhost:一种 virtio 高性能的后端驱动实现

什么是 vhost vhost 是 virtio 的一种后端实现方案,在 virtio 简介中,我们已经提到 virtio 是一种半虚拟化的实现方案,需要虚拟机...

1.1K60

扫码关注云+社区

领取腾讯云代金券