使用 Node.js 搭建一個 API 網關

使用 Node.js 搭建一個 API 網關

外部客戶端訪問微服務架構中的服務時,服務端會對認證和傳輸有一些常見的要求。API 網關提供共享層來處理服務協議之間的差異,并滿足特定客戶端(如桌面瀏覽器、移動設備和老系統)的要求。

微服務和消費者

微服務是面向服務的架構,團隊可以獨立設計、開發和發布應用程序。它允許在系統各個層面上的技術多樣性,團隊可以在給定的技術難題中使用最佳語言、數據庫、協議和傳輸層,從而受益。例如,一個團隊可以使用 HTTP REST 上的 JSON,而另一個團隊可以使用 HTTP/2 上的 gRPC 或 RabbitMQ 等消息代理。

在某些情況下使用不同的數據序列化和協議可能是強大的,但要使用我們的產品的客戶可能有不同的需求。該問題也可能發生在具有同質技術棧的系統中,因為客戶可以從桌面瀏覽器通過移動設備和游戲機到遺留系統。一個客戶可能期望 XML 格式,而另一個客戶可能希望 JSON 。在許多情況下,您需要同時支持它們。

當客戶想要使用您的微服務時,您可以面對的另一個挑戰來自于通用的共享邏輯(如身份驗證),因為您不想在所有服務中重新實現相同的事情。

總結:我們不想在我們的微服務架構中實現我們的內部服務,以支持多個客戶端并可以重復使用相同的邏輯。這就是 API 網關出現的原因,其作為共享層來處理服務協議之間的差異并滿足特定客戶端的要求。

什么是 API 網關?

API 網關是微服務架構中的一種服務,它為客戶端提供共享層和 API,以便與內部服務進行通信。API 網關可以進行路由請求、轉換協議、聚合數據以及實現共享邏輯,如認證和速率限制器。

您可以將 API 網關視為我們的微服務世界的入口點。

我們的系統可以有一個或多個 API 網關,具體取決于客戶的需求。例如,我們可以為桌面瀏覽器、移動應用程序和公共 API 提供單獨的網關。

API Gateway

API 網關作為微服務的切入點

Node.js 用于前端團隊的 API 網關

由于 API 網關為客戶端應用程序(如瀏覽器)提供了功能,它可以由負責開發前端應用程序的團隊實施和管理。

這也意味著用哪種語言實現 API Gateway 應由負責特定客戶的團隊選擇。由于 JavaScript 是開發瀏覽器應用程序的主要語言,即使您的微服務架構以不同的語言開發,Node.js 也可以成為實現 API 網關的絕佳選擇。

Netflix 成功地使用 Node.js API 網關及其 Java 后端來支持廣泛的客戶端 - 了解更多關于它們的方法閱讀 The "Paved Road" PaaS for Microservices at Netflix 這篇文章

Netflix 處理不同客戶端的方法, 資源

API 網關功能

我們之前討論過,可以將通用共享邏輯放入您的 API 網關,本節將介紹最常見的網關職責。

路由和版本控制

我們將 API 網關定義為您的微服務的入口點。在您的網關服務中,您可以指定從客戶端路由到特定服務的路由請求。您甚至可以通過路由處理版本或更改后端接口,而公開的接口可以保持不變。您還可以在您的 API 網關中定義與多個服務配合的新端點。

API Gateway - Entry point

API 網關作為微服務入口點

網關設計的升級

API 網關方法也可以幫助您分解您的整體應用程序。在大多數情況下,在微服務端重構一個系統不是一個好主意也是不可能的,因為我們需要在重構期間為業務發送新的以及原有的功能。

在這種情況下,我們可以將代理或 API 網關置于我們的整體應用程序之前,將新功能作為微服務實現,并將新端點路由到新服務,同時通過原有的路由服務舊端點。這樣以后,我們也可以通過將原有功能轉變為新服務來分解整體。

隨著網關設計的升級,我們可以實現整體架構到微型服務的平滑過渡

API Gateway - Evolutionary design

API 網關設計的升級

認證

大多數微服務基礎設施需要進行身份驗證。將共享邏輯(如身份驗證)添加到 API 網關可以幫助您保持您的服務的體積變小以及可以集中管理域。

在微服務架構中,您可以通過網絡配置將您的服務保護在 DMZ (保護區)中,并通過 API 網關向客戶公開。該網關還可以處理多個身份驗證方法。例如,您可以同時支持基于 cookietoken 的身份驗證。

API Gateway - Authentication

具有認證功能的 API 網關

數據匯總

在微服務架構中,可能客戶端所需要的數據的聚合級別不同,比如對在各種微服務中產生的非規范化數據實體。在這種情況下,我們可以使用我們的 API 網關來解決這些依賴關系并從多個服務收集數據。

在下圖中,您可以看到 API 網關如何將用戶和信用信息作為一個數據返回給客戶端。請注意,這些數據由不同的微服務所擁有和管理。

API Gateway - Data aggregation

序列化格式轉換

我們需要支持客戶端不同的數據序列化格式這樣子的需求可能會發生。

想象一下我們的微服務使用 JSON 的情況,但我們的客戶只能使用 XML APIs。在這種情況下,我們可以在 API 網關中把 JSON 轉換為 XML,而不是在所有的微服務器中分別進行實現。

API Gateway - Data serialization format transformation

協議轉換

微服務架構允許多通道協議傳輸從而獲取多種技術的優勢。然而,大多數客戶端只支持一個協議。在這種情況下,我們需要轉換客戶端的服務協議。

API 網關還可以處理客戶端和微服務器之間的協議轉換。

在下一張圖片中,您可以看到客戶端希望通過 HTTP REST 進行的所有通信,而內部的微服務使用 gRPC 和 GraphQL 。

API Gateway - Protocol transformation

速率限制和緩存

在前面的例子中,您可以看到我們可以把通用的共享邏輯(如身份驗證)放在 API 網關中。除了身份驗證之外,您還可以在 API 網關中實現速率限制,緩存以及各種可靠性功能。

超負荷的 API 網關

在實現您的 API 網關時,您應避免將非通用邏輯(如特定數據轉換)放入您的網關。

服務應該始終擁有他們的數據域全部所有權。構建一個超負荷的 API 網關,讓微服務團隊來控制,這違背了微服務的理念。

這就是為什么你應該關注你的 API 網關中的數據聚合 - 你應該避免它有大量邏輯甚至可以包含特定的數據轉換或規則處理邏輯。

始終為您的 API 網關定義明確的責任,并且只包括其中的通用共享邏輯。

Node.js API 網關

當您希望在 API 網關中執行簡單的操作,比如將請求路由到特定服務,您可以使用像 nginx 這樣的反向代理。但在某些時候,您可能需要實現一般代理不支持的邏輯。在這種情況下,您可以在 Node.js 中實現自己的 API 網關。

在 Node.js 中,您可以使用 http-proxy 軟件包簡單地代理對特定服務的請求,也可以使用更多豐富功能的 express-gateway 來創建 API 網關。

在我們的第一個 API 網關示例中,我們在將代碼委托給 user 服務之前驗證請求。

    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 網關的過度使用,因為很多邏輯可以從服務團隊中獲得控制。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容