Node做BFF中間層架構優化前端開發體驗并提升系統整體性能。

文章目錄

      • 1. BFF 層的定位
      • 2. 技術選型
      • 3. 架構設計
        • 3.1 分層設計
        • 3.2 示例架構
      • 4. 核心功能實現
        • 4.1 數據聚合
        • 4.2 權限校驗
        • 4.3 緩存優化
      • 5、實戰示例
      • 1. 場景說明
      • 2. ECharts 數據格式要求
      • 3. BFF 層實現步驟
        • 3.1 接收前端參數
        • 3.2 調用后端服務獲取數據
      • 4. 前端使用
  • 總結


在使用 Node.js 構建 BFF(Backend for Frontend)層架構時,核心思想是為前端應用(如 Web、移動端或桌面應用)提供定制化的 API 接口,將后端復雜的服務邏輯抽象化、聚合化,從而優化前端開發體驗并提升系統整體性能。

以下是基于 Node.js 構建 BFF 層架構的一些關鍵點和實踐方法:


1. BFF 層的定位

  • 職責

    • 為前端提供專用的接口,屏蔽后端服務的復雜性。
    • 聚合多個微服務的數據,減少前端的請求次數。
    • 處理與前端相關的邏輯(如權限校驗、數據格式轉換、多端適配等)。
  • 位置

    • 位于前端與后端服務(如微服務、數據庫等)之間,作為中間層。

2. 技術選型

  • Node.js 框架

    • Express.js:輕量級、靈活,適合快速開發。
    • Koa.js:基于 async/await 的現代框架,代碼更簡潔。
    • NestJS:基于 TypeScript 的企業級框架,適合大型項目。
  • 其他工具

    • GraphQL:如果需要更靈活的數據查詢,可以用 Apollo Server 或 GraphQL.js。
    • 微服務通信:使用 axiosnode-fetch 調用后端服務。
    • 緩存:使用 Redis 或內存緩存(如 node-cache)優化性能。
    • 監控與日志:集成 winstonpino 等日志庫,以及 Prometheus 等監控工具。

3. 架構設計

3.1 分層設計
  • 路由層:處理 HTTP 請求,定義 API 接口。
  • 服務層:封裝業務邏輯,調用后端服務或數據庫。
  • 數據聚合層:從多個數據源獲取數據并整合成前端需要的格式。
  • 適配器層:處理與前端相關的邏輯(如格式轉換、權限校驗等)。
3.2 示例架構
plaintextFrontend (Web/Mobile)↓BFF Layer (Node.js)├── Router (定義 API 接口)├── Service (業務邏輯)├── Aggregator (數據聚合)├── Adapter (前端適配)└── External Services (調用后端微服務/數據庫)

4. 核心功能實現

4.1 數據聚合
  • 假設有一個電商應用,前端需要展示商品詳情,包括商品信息、庫存、用戶評價等。

  • BFF 層可以調用多個微服務:

    • 商品服務:獲取商品基本信息。
    • 庫存服務:獲取商品庫存。
    • 評價服務:獲取用戶評價。
  • BFF 層將這些數據整合后返回給前端。

示例代碼

	const express = require('express');const axios = require('axios');const app = express();app.get('/product/:id', async (req, res) => {const productId = req.params.id;try {// 調用多個微服務const [product, inventory, reviews] = await Promise.all([axios.get(`https://product-service/api/products/${productId}`),axios.get(`https://inventory-service/api/inventory/${productId}`),axios.get(`https://review-service/api/reviews/${productId}`),]);// 聚合數據const result = {product: product.data,inventory: inventory.data,reviews: reviews.data,};res.json(result);} catch (error) {res.status(500).send('Error fetching product data');}});app.listen(3000, () => {console.log('BFF server running on port 3000');});
4.2 權限校驗
  • 在 BFF 層統一處理用戶認證和權限校驗。
  • 使用 JWT 或 OAuth2.0 驗證用戶身份。

示例代碼

	const jwt = require('jsonwebtoken');function authenticateToken(req, res, next) {const authHeader = req.headers['authorization'];const token = authHeader && authHeader.split(' ')[1];if (token == null) return res.sendStatus(401);jwt.verify(token, 'your-secret-key', (err, user) => {if (err) return res.sendStatus(403);req.user = user;next();});}app.get('/secure-data', authenticateToken, (req, res) => {res.json({ message: 'This is secure data', user: req.user });});
4.3 緩存優化
  • 使用 Redis 緩存熱點數據,減少對后端服務的調用。

示例代碼

	const redis = require('redis');const client = redis.createClient();app.get('/cached-data/:id', async (req, res) => {const id = req.params.id;const cacheKey = `data:${id}`;client.get(cacheKey, async (err, data) => {if (data) {res.json(JSON.parse(data));} else {const result = await axios.get(`https://some-service/api/data/${id}`);client.setex(cacheKey, 3600, JSON.stringify(result.data)); // 緩存 1 小時res.json(result.data);}});});

5、實戰示例

在基于 ECharts 圖表的數據展示場景中,BFF(Backend for Frontend)層可以承擔數據聚合和格式化的任務,從而讓前端專注于圖表的渲染邏輯,同時減少前端與多個后端服務的交互復雜度。


1. 場景說明

假設需要展示一個包含以下信息的 ECharts 圖表:

  • 銷售數據(從 sales-service 獲取)。
  • 用戶增長數據(從 user-service 獲取)。
  • 時間范圍由前端傳遞(如最近 7 天、30 天等)。

BFF 層的目標是:

  1. 接收前端的時間范圍參數。
  2. 調用多個后端服務獲取數據。
  3. 聚合數據并格式化為 ECharts 所需的格式。
  4. 返回給前端。

2. ECharts 數據格式要求

ECharts 圖表通常需要以下數據結構:

  • X 軸數據:時間、分類等。
  • Y 軸數據:數值(如銷售額、用戶數等)。
  • 系列(series) :不同數據類型的集合。

示例 ECharts 配置

	option = {xAxis: {type: 'category',data: ['2023-10-01', '2023-10-02', '2023-10-03'], // X 軸數據},yAxis: {type: 'value',},series: [{name: '銷售額',type: 'line',data: [120, 200, 150], // Y 軸數據},{name: '用戶數',type: 'line',data: [50, 80, 70],},],};

3. BFF 層實現步驟

3.1 接收前端參數

前端通過查詢參數傳遞時間范圍,例如:

	GET /chart-data?startDate=2023-10-01&endDate=2023-10-07
3.2 調用后端服務獲取數據

BFF 層調用多個服務獲取數據,例如:

  • sales-service:返回指定時間范圍內的銷售數據。
  • user-service:返回指定時間范圍內的用戶增長數據。

示例代碼

	const express = require('express');const axios = require('axios');const app = express();app.get('/chart-data', async (req, res) => {const { startDate, endDate } = req.query;try {// 調用銷售服務const salesResponse = await axios.get(`https://sales-service/api/sales`, {params: { startDate, endDate },});const salesData = salesResponse.data; // 假設返回 [{ date: '2023-10-01', amount: 120 }, ...]// 調用用戶服務const userResponse = await axios.get(`https://user-service/api/users`, {params: { startDate, endDate },});const userData = userResponse.data; // 假設返回 [{ date: '2023-10-01', count: 50 }, ...]// 數據聚合與格式化const dateSet = new Set();const salesMap = {};const userMap = {};// 收集所有日期salesData.forEach(item => dateSet.add(item.date));userData.forEach(item => dateSet.add(item.date));// 構建日期數組const xAxisData = Array.from(dateSet).sort();// 填充銷售數據salesData.forEach(item => {salesMap[item.date] = item.amount;});// 填充用戶數據userData.forEach(item => {userMap[item.date] = item.count;});// 構建 Y 軸數據const salesSeries = xAxisData.map(date => salesMap[date] || 0);const userSeries = xAxisData.map(date => userMap[date] || 0);// 返回 ECharts 所需格式res.json({xAxis: xAxisData,series: [{ name: '銷售額', type: 'line', data: salesSeries },{ name: '用戶數', type: 'line', data: userSeries },],});} catch (error) {res.status(500).send('Error fetching chart data');}});app.listen(3000, () => {console.log('BFF server running on port 3000');});

4. 前端使用

前端只需要調用 BFF 層提供的接口,并直接將返回的數據傳遞給 ECharts:

	fetch('/chart-data?startDate=2023-10-01&endDate=2023-10-07').then(response => response.json()).then(data => {const option = {xAxis: {type: 'category',data: data.xAxis,},yAxis: {type: 'value',},series: data.series,};const chart = echarts.init(document.getElementById('main'));chart.setOption(option);});

總結

通過以上方法,你可以使用 Node.js 構建一個高效、靈活的 BFF 層架構,為前端提供更好的開發體驗,同時優化后端服務的調用效率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901874.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901874.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901874.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

文件系統 軟硬連接

🌻個人主頁:路飛雪吖~ 🌠專欄:Linux 目錄 一、理解文件系統 🌠磁盤結構 二、軟硬連接 🌟軟硬鏈接 🌠軟鏈接: 🌠硬鏈接: 🌟理解軟硬鏈接的應…

單片機 | 基于51單片機的自動循跡小車設計

以下是一個基于51單片機的自動循跡小車設計詳解,包含原理、公式和完整代碼: 一、系統原理 核心模塊: 傳感器:紅外對管(TCRT5000)x4主控芯片:STC89C52RC(51單片機)電機驅動:L298N驅動模塊電源:7.4V鋰電池(電機) + 5V穩壓(單片機)工作原理: 紅外對管發射紅外線,…

2025.04.17【Stacked area】| 生信數據可視化:堆疊區域圖深度解析

文章目錄 生信數據可視化:堆疊區域圖深度解析堆疊面積圖簡介為什么使用堆疊面積圖如何使用R語言創建堆疊面積圖安裝和加載ggplot2包創建堆疊面積圖的基本步驟示例代碼 解讀堆疊面積圖堆疊面積圖的局限性實際應用案例示例:基因表達量隨時間變化 結論 生信…

基于單片機的智能養生油炸爐系統設計與實現

標題:基于單片機的智能養生油炸爐系統設計與實現 內容:1.摘要 本文針對傳統油炸爐功能單一、無法滿足現代養生需求的問題,設計并實現了基于單片機的智能養生油炸爐系統。通過采用STC89C52單片機作為控制核心,結合溫度傳感器、液位傳感器、繼電器等硬件&…

QML與C++:基于ListView調用外部模型進行增刪改查(附自定義組件)

目錄 引言相關閱讀項目結構文件組織 核心技術實現1. 數據模型設計聯系人項目類 (datamodel.h)數據模型類 (datamodel.h)數據模型實現 (datamodel.cpp) 2. 主程序入口點 (main.cpp)3. 主界面設計 (Main.qml)4. 聯系人對話框 (ContactDialog.qml)5. 自定義組件CustomTextField.qm…

【MySQL】事務ACID理解記憶

事務的 ACID 特性詳解 數據庫中的 事務(Transaction) 是一組操作的集合,這些操作要么全部執行,要么全部不執行。為了保證事務可靠執行,必須滿足 ACID 四大特性: 特性英文縮寫簡要說明原子性Atomicity事務…

MYSQL “Too Many Connections“ 錯誤解決

1.查詢當前連接數 show status like "Threads_connected"; 2.查詢數據庫最大連接數 show variables like "max_connections" 3.查詢所有活動連接 show processlist; 4.根據查詢結果觀察是否有長時間未被釋放的連接 參數解釋 : 字段說明id連接的唯一…

Python爬蟲實戰:基于 Scrapy 框架的微博數據爬取研究

一、引言 1.1 研究背景 在當今數字化時代,社交媒體已成為信息傳播和公眾交流的重要平臺。微博作為國內極具影響力的社交媒體之一,每日產生海量的用戶生成內容,涵蓋新聞資訊、社交互動、娛樂八卦、熱點話題討論等多個領域。這些數據不僅反映了公眾的興趣偏好、情感態度和社…

貓咪如廁檢測與分類識別系統系列【九】視頻檢測區域在線繪制+支持攝像頭+網絡攝像頭+整體構建【上】

前情提要 家里養了三只貓咪,其中一只布偶貓經常出入廁所。但因為平時忙于學業,沒法時刻關注牠的行為。我知道貓咪的如廁頻率和時長與健康狀況密切相關,頻繁如廁可能是泌尿問題,停留過久也可能是便秘或不適。為了更科學地了解牠的如…

【AI插件開發】Notepad++ AI插件開發實踐:支持多平臺多模型

引言 上篇文章我們的Notepad插件介紹到Dock窗口集成,本篇將繼續完善插件功能,主要包括兩個部分: 支持多平臺、多模型支持多種授權驗證、接口類型 一、多平臺 原先的配置項很簡單: // PluginConf.h class PlatformConf { publ…

【C#】Socket通信的使用

在C#中,Socket通信是一種用于實現網絡通信的底層技術。通過Socket,程序可以在網絡上與其他設備進行數據交換。以下是如何使用C#中的System.Net.Sockets命名空間來實現Socket通信的詳細步驟。 1. Socket通信的基本概念 Socket: 一個Socket是網絡通信的端…

2024年第九屆團隊程序設計天梯賽c++題解L1-L3-1(附PTA網址)

L1-1 編程解決一切 5分 L1-097 編程解決一切 - 團體程序設計天梯賽-練習集 (pintia.cn)https://pintia.cn/problem-sets/994805046380707840/exam/problems/type/7?problemSetProblemId1781658570803388416 #include<bits/stdc.h> #define int long long using namesp…

ICMAN防水觸摸芯片 - 復雜環境下精準交互,提升觸控體驗

▍核心優勢 ◆ 超強抗干擾能力 ◆ 工業級設計&#xff0c;一致性和穩定性好 ▍提供場景化解決方案 【智能廚電矩陣】抽油煙機檔位調節 | 電磁爐火力觸控 | 洗碗機模式切換 【衛浴設備方案】淋浴房霧化玻璃控制 | 智能馬桶觸控面板 | 浴缸水位感應 【工業控制應用】儀器儀…

Golang|抽獎相關

文章目錄 抽獎核心算法生成抽獎大轉盤抽獎接口實現 抽獎核心算法 我們可以根據 單商品庫存量/總商品庫存量 得到每個商品被抽中的概率&#xff0c;可以想象這樣一條 0-1 的數軸&#xff0c;數軸上的每一段相當于一種商品&#xff0c;概率之和為1。 抽獎時&#xff0c;我們會生…

OpenCV 圖形API(43)顏色空間轉換-----將 BGR 圖像轉換為 LUV 色彩空間函數BGR2LUV()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 將圖像從BGR色彩空間轉換為LUV色彩空間。 該函數將輸入圖像從BGR色彩空間轉換為LUV。B、G和R通道值的傳統范圍是0到255。 輸出圖像必須是8位無符…

【Python】用Python寫一個俄羅斯方塊玩玩

【Python】用Python寫一個俄羅斯方塊玩玩 一、引言1.成品效果展示 二、思考準備1.思考設計2.代碼設計2.1 游戲頁面2.2 控件設計2.2.1 方塊生成2.2.2 方塊碰撞2.2.3 方塊消融2.2.4 游戲主循環2.2.5 游戲窗口 三、游戲完整版 一、引言 今日看到侄子在玩游戲&#xff0c;湊近一看…

維港首秀!沃飛長空AE200亮相香港特別行政區

4月13日-16日&#xff0c;第三屆香港國際創科展在香港會議展覽中心盛大舉辦。 作為國內領先、國際一流的eVTOL主機廠&#xff0c;沃飛長空攜旗下AE200批產構型登陸國際舞臺&#xff0c;以前瞻性的創新技術與商業化應用潛力&#xff0c;吸引了來自全球17個國家及地區的行業領袖…

Openfein實現遠程調用的方法(實操)

文章目錄 環境準備一、URL中接收參數二、接收一個參數三、接收多個參數四、傳遞對象五、傳遞JSON格式數據 環境準備 下面的配置&#xff0c;服務調用方加入即可。 依賴導入&#xff1a; <!-- openfeign依賴--><dependency><groupId>org.springframe…

Bright+Data網頁解鎖器:旅游行業數據革命的“隱形引擎”

在數字經濟浪潮中&#xff0c;旅游行業正經歷前所未有的變革。當消費者指尖滑動間完成跨國酒店預訂&#xff0c;當航空公司每秒調整萬次艙位價格&#xff0c;背后是一場無聲的數據戰爭。而在這場戰爭中&#xff0c;BrightData網頁解鎖器正成為旅游企業破局的關鍵武器——它像一…

OpenCV 圖形API(38)圖像濾波-----Sobel 算子操作函數Sobel()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::gapi::Sobel 函數是 OpenCV 的 G-API 模塊中用于執行 Sobel 算子操作的一個函數&#xff0c;主要用于圖像的邊緣檢測。Sobel 算子通過計算圖…