[译] 用 Node.js 搭建 API Gateway

咱们团队的后端服务中,一开始只有一个大服务,全部的东西都往里面写,能够想象下,当这个服务变得不断的庞大,将会变得多么难以维护。后来逐渐把一些数据服务抽离成单独的 API 服务,在原有的服务里,就还剩一些模板渲染,数据聚合还有一些耦合的业务逻辑。目前来讲拆的还不够干净,咱们的目标实际上是但愿这个旧的服务充当一个 API Gateway,或者说一个给前端用的中间层。单一职责原则,实际上是一个很重要的解耦方式,一个服务干好一件事就行了。偶然间看到下面的文章,虽然只是一些很简单的介绍,也让我了解到不少东西。也分享给 你们看看。前端

阅读原文node

客户端通常都须要通过一些认证以及知足在数据传输时的安全要求,才能得到访问微服务架构中的服务的权利。不一样的服务在认证上都会或多或少存在一些差别,API Gateway 就像一个集线器,用它来抹平各类服务协议之间的差别,并知足对特定客户端的特殊处理。他的存在,方便了客户端对各种服务的享用。nginx

微服务和消费者

微服务适合用在团队能够独立设计、开发、运行服务的架构体系中。它容许系统中的各个服务存在技术多样性,团队能够在适合的场景使用合适的开发语言、数据库和网络协议。例如,一个团队中使用 JSON 和 HTTP REST,而另外一个团队则可能使用 gRPC 和 HTTP/2 或者像 RabbitMQ 这样的消息代理。数据库

有些场景中使用不一样的数据序列化方式和协议可能收益巨大,可是须要使用咱们服务的客户端可能会有不一样的需求。因为存在各类各样的客户端,须要咱们支持的数据格式也是多种多样,好比一个客户端可能但愿拿到的数据是 XML 格式的,而另外一个客户端则但愿数据是 JSON。另外一个你可能须要面对的问题是,可能不一样服务之间存在着一些公共的逻辑(好比权限认证之类),总不能在每一个服务里都实现一遍吧?express

总结:咱们不想把一些支持多个客户端等相关的公用逻辑重复实如今微服务中,咱们须要一个 API Gateway 来提供一个中间层来处理服务协议之间的差别,并知足特定客户端的需求。json

什么是 API Gateway

API 网关是微服务架构中的一种服务,它为客户端提供共享层和 API,以便与内部服务进行通讯。 API 网关能够路由请求,转换协议,聚合数据,并实现一些共享逻辑,如身份验证和速率限制器等。后端

你能够将 API Gateway 看作是一个享用各类微服务的入口。api

咱们的系统能够有一个或多个 API Gateway,这具体取决于客户端的需求。例如,咱们能够为桌面浏览器,移动应用程序和公共API提供单独的网关。promise

image

前端团队的Node.js API Gateway

因为 API Gateway 为客户端应用程序(如浏览器)提供了支持,它能够由负责前端应用程序的团队来实现和管理。浏览器

这也意味着 API Gateway 的实现语言应由负责客户端的团队选择。因为 JavaScript 是开发浏览器应用程序的主要语言,即便你的微服务架构用不一样的语言开发,Node.js 也能够成为实现 API Gateway 的绝佳选择。
Netflix 成功地使用 Node.js API Gateway 及其 Java 后端来支持普遍的客户端, 了解更多

image

API Gateway 的实用性

咱们以前讨论过,能够将通用共享逻辑放入 API Gateway,本节将介绍其常见用法。

路由和版本控制

咱们将 API Gateway 定义为微服务的入口。 在你的 API Gateway 中,你能够将请求从客户端路由到指定的服务。 你甚至能够在路由期间对服务程序的版本进行选择或更改后端接口,而公开的接口能够保持不变。你还能够在你的 API Gateway 中集合多个微服务到一点。

image

迭代设计

API Gateway 能够帮助你分解臃肿的应用程序。因为业务的不断迭代,从头开始把整个应用重写成一个微服务架构的系统彷佛不太可行。

在这种状况下,咱们能够将代理或 API Gateway 置于咱们的总体应用以前,并将新功能做为微服务实现,只须要保证 API Gateway 能将新接口路由到新服务,同时保证旧接口依然可以访问。慢慢的咱们要把这些旧的服务迁移成微服务以达到分解臃肿应用程序的目的。
经过小步迭代设计,咱们可以平滑的从庞大的总体过渡到微服务架构。

image

认证

大多数微服务是须要经过认证才可使用的。将相似身份验证的共享逻辑放在 API Gateway 上可让你的微服务更加专一。

在微服务架构中,您能够经过网络配置将服务放置于 DMZ(非军事区域)中,并经过API Gateway 将其暴露给客户端。该网关还能够处理多个身份验证方法,例如,能够支持基于cookie和基于 token 的身份验证。

数据聚合

在微服务架构中,客户端可能会须要不一样聚合程度的数据。 在这种状况下,咱们可使用 API Gateway 来解决这些依赖关系并从多个服务收集数据。

image

序列化格式转换

这种问题发生在不一样客户端须要不一样格式数据的需求中。

想象一下,在微服务中若是咱们使用了 JSON,可是在某个客户端中只支持 XML 的 API,这个时候怎么办?咱们彻底能够把 JSON 转换 XML 这一过程放在 API Gateway 中,而不是在每一个微服务中实现。

image

协议转换

微服务架构容许使用不一样的协议以便于得到使用不一样技术的优点。然而,大多数客户端只支持一种协议。在这种状况下,咱们须要转换客户端的服务协议。

API Gateway 也能够成为介于客户端和微服务之间的一个协议转换层。

下面的图片中你能够看到,客户端只使用 HTTP REST 来和各类服务交换信息,而实际上咱们内部的各类微服务能够基于不一样的规范、协议来进行信息传递。

image

速率控制和缓存

除了身份验证以外,你还能够在 API Gateway 中实现速率限制,缓存和各类可靠性相关的功能。

过于庞大的 API Gateway

在实现 API Gateway 时,应当避免将非通用逻辑(如领域特定数据转换)放入其中。

服务应始终对其数据域拥有彻底的全部权。 构建一个过于庞大的 API Gateway,从服务团队争夺控制权,这违反了微服务的理念。

这就是为何你应该注意你的API网关中的数据聚合 —— 若是你明确它的职责,它能够是很强大的,应当避免在 API Gateway 中处理业务逻辑,是谁的事情就交给谁干,必定要明确其在整个架构中的角色。

Node.js Gateways

若是你但愿在 API Gateway 中执行一些简单的操做,例如将请求路由到特定的服务,你可使用像nginx这样的反向代理。 但在某些时候,你可能须要实现通常代理不支持的逻辑。 在这种状况下,你能够在 Node.js 中实现本身的 API Gateway。

在 Node.js 中,你可使用 http-proxy 完成一些简单的代理请求的服务,固然也可使用具备更多功能的 express-gateway。

在第一个 API Gateway 示例中,咱们在其代理请求到真实的服务以前,先进行权限认证。

const express = require('express') 
const httpProxy = require('express-http-proxy')  
const app = express()

const userServiceProxy = httpProxy('https://user-service')

// Authentication
app.use((req, res, next) => {
  // TODO: my authentication logic  
  next()
})
// Proxy request 
app.get('/users/:userId', (req, res, next) => {    
  userServiceProxy(req, res, next)
})

另外一种方式是由 API Gateway 向微服务发送请求,再将响应回馈给客户端:

const express = require('express')  
const request = require('request-promise-native')  
const app = express()
// Resolve: 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)
})

总结:

API Gateway 提供了一个中间层来协调客户端和微服务架构。它有助于帮助咱们完成单一职责原则,让咱们的应用或者服务持续的关注一件事。你能够将通用逻辑放入 API Gateway 中,可是也应该注意不要过分的使用 API Gateway。

相关文章
相关标签/搜索