標籤:

js中什麼技術能合併多個前端請求,並生成一個json文件發送?

js中什麼技術能合併多個前端請求,並生成一個json文件發送?


你的需求不正是現在 Facebook的GraphQL嗎

GraphQL 是一個由Facebook提出的 應用層查詢語言. 使用 GraphQL, 你可以基於圖模式定義你的後端. 然後客戶端就可以請求所需要的數據集。

因此, 你不必因為客戶端數據需求的變更而改變你的後端. 這解決了管理REST API中的最大的問題.

GraphQL同樣能夠讓客戶端程序高效地批量獲取數據.

例如, 看一看下面這個GraphQL請求:

{
latestPost {
_id,
title,
content,
author {
name
},
comments {
content,
author {
name
}
}
}
}

這個 GraphQL 請求獲取了一篇博客文章和對應評論與作者信息的數據. 下面是請求的返回結果:

{
"data": {
"latestPost": {
"_id": "03390abb5570ce03ae524397d215713b",
"title": "New Feature: Tracking Error Status with Kadira",
"content": "Here is a common feedback we received from our users ...",
"author": {
"name": "Pahan Sarathchandra"
},
"comments": [
{
"content": "This is a very good blog post",
"author": {
"name": "Arunoda Susiripala"
}
},
{
"content": "Keep up the good work",
"author": {
"name": "Kasun Indi"
}
}
]
}
}
}

如果你使用的是REST的話,你需要調用多個REST API的請求才能獲取這些信息。

GraphQL是一個規範

因此, 它可以用於任何平台或語言. 它有一個參考的實現 JavaScript, 由Facebook維護. 還有許多社區維護的實現有許多種語言.

這裡是它的規範:http://facebook.github.io/graphql/

現在github的v4版本API 也是基於GraphQL 設計的

GitHub GraphQL API v4


我以前干過這事,甚至還直接在 Nginx 里寫了個插件,把前端打包好的請求拆分開來丟給不同的業務邏輯伺服器,最後再匯總結果丟回客戶端。

起初也覺得會快一點,畢竟大多數瀏覽器有並發 HTTP 連接數量限制,等上幾個 round-trip time 挺慢的;更何況多出來幾個 HTTP 請求頭的處理也會帶來 overhead。

但後來確實發現很多時候這樣的體驗更糟糕,因為後端得等所有請求都處理完畢再丟給前端,所以前端很多明明可以先行展示出來的東西都被拖後。

最終我走上了一條邪路:直接建立一個 WebSocket 開著,前端每個請求通過那個 WebSocket 直接發上去,而每個響應也直接通過那個 WebSocket 第一時間就返回。這樣保證了不用重新建立連接,並且把 HTTP 頭帶來的 overhead 都丟掉了。

但這也就導致我得在兩端自行對 WebSocket 里的內容進行 demultiplexing 的操作。最後的最後,我發現自己似乎在重造 HTTP 的輪子。

所以還是別折騰,直接用 HTTP/2 吧…已經解決了大多數 concern 了。


把響應合併成一個 JSON 並不見得會提高載入速度。多個請求可以進行並行載入,而單個 HTML 可以進行流式渲染,有很多方法會比一個合併的 JSON 響應更快。

推薦看一下 Jake Archibald 這篇博文:https://jakearchibald.com/2016/fun-hacks-faster-content/


你要的在這裡:Batch Request

我的業務上目前用的也是這個,GraphQL畢竟是把牛刀了,要用這個還得熟悉一大套東西;

然後我用這個解決的場景問題是:單頁式應用里頁面切換時,某個頁面請求並發數超過了瀏覽器並發上限導致部分請求排隊。

batch-request庫的缺點是,不支持流式請求合併,即你的合併請求必須等所有原子請求都返回後才能拼裝返回給前端,所以我現在在寫一個流式請求合併庫來解決這個問題,包括了nodejs端和browser端的stream-fetch,但因為時間問題只初步完成了nodejs端,等我後面寫完了,再放上來獻醜。

另外如果你的用戶瀏覽器屌到能支持HTTP2,這個請求合併也沒太大必要了,部分支持的話就是做個兼容處理,支持h2的就h2,不支持的走請求合併:)


看什麼需求了。

如果是為了提高響應速度,無依賴關係的請求完全可以在前端做到並發請求,Service Worker 以及合理的資源載入順序足矣。有條件可以上 SPDY / H2。

如果請求之間存在依賴關係,必須用請求 A 的結果去發起請求 B,那優化起來肯定需要後端的配合了,最簡單的方法就是加 BFF 層(比如 Node.js 對前端開發就很友好,PHP 也行),前端去負責維護這一塊,根據業務自己組裝介面。可以用到的技術就有很多了,比如 GraphQL、WebSocket 等。很多情況下都不需要因為介面組裝的問題去麻煩後端,尤其是微服務、Serverless 等理念出來以後。


最簡單的方法就是後端寫一個介面,把你要調用的介面包起來


歡迎回到伺服器端渲染


Service Worker API

題目似乎沒有問後端該怎麼做,那麼只要在前端把請求攔下來合併就行了。剩下的事情誰會關心呢?


這取決於你的後端業務支持你怎麼做,有的回答提到了graphql,也是需要server端的支持的,graphql本身引入server端也並非是一件容易的事,很多server端技術可能受到依賴和歷史原因不能直接使用社區的grphql組件。

最簡單的辦法還是需要聚合的地方封裝一個,可以並發查詢的就使用Promise.all,有介面依賴關係的就使用generator或者async await來實現。

下文所依賴的語法都包含在 babel-presets es2015 stage-2 里

//依賴介面
import {service0,service1,service2} from "../service";

//封裝無依賴關係的聚合介面
export async function compilationService(...args){
return Promise.all([service0(args[0]),service1(args[1]),service2(args[2])]);
}

//封裝依賴介面
export async function sequenceDataFlowService(...args){
const data0 = await service0(args);
const data1 = await service1(data0);
const data2 = await service2(data0,data1);
//...
return [data0,data1,data2];
}

//使用無依賴關係的介面
async function controllerMethod0(){
const [data0,data1,data2] = await compliationService(1,2,3);
}

//使用依賴關係
async function controllerMethod0(){
const [data0,data1,data2] = await sequenceDataFlowService(1,2,3);
}

當然這只是最理想的情況,這裡面的錯誤處理等等還是要喝一壺的...


Ajax技術。

其他的統統是由後端負責。

Graphql也就是一個查詢的工具,指定輸入,然後輸出。所以graphql並不一定得是HTTP, websock, TCP鏈接都可以。只要給定輸入,然後輸入到設置好的Graphql模型,然後輸出結果。

所以不要問什麼技術。就是一個通信協議。

你甚至可以屬於自己的協議。

跟後端約定數據格式而已,然後後端去解析這個格式。


可以用rxjs處理,非同步請求,同步處理。


並不是很懂你想合併成一個json的意義是什麼。

如果你是多個請求合併之後,後端不拆開處理,那麼這其中就有如何同步不同請求之間的先後順序的問題。比如說後端需要前端兩個請求的內容,但是此時前端只給了一個,那麼前端不得不去等待。也沒啥太大的用處。

如果後端拆開處理的話,就不如採用 h2,交給協議去做。

我看到有人說到用,http over websocket的方案,我之前也確實嘗試過,但是最後發現,和手寫一個 http 協議沒啥區別。但是這確實能在一定程度上提升速度,但是問題很多。比如請求時連接中斷怎麼辦,如何自動重連。如何和舊系統兼容等等的問題。


graphql+relay

麻煩是麻煩點,看你應用了。要是大廠的複雜api可以上。

要是api不複雜,那就借著這套東西的理念自己造個小輪子吧


推薦閱讀:

Node.js 都應用在什麼項目上?這些項目為什麼選擇 Node.js?
如何利用mongodb+node.js完成一個搜索的功能?
有哪些比較好用的nodejs模塊?
有哪些值得推薦的針對 Node.js 本身而非 Express 框架之類的學習資料?
NodeJS的desktop應用開發中,關於Electron的中文文檔或者博客之類的很少?

TAG:Nodejs |