[英]What is the best approach to stream JSON from a REST API to an Express app?
我有一個基於分子的微服務,它的端點輸出一個大的 JSON object (大約數萬個對象)
這是一個結構化的 JSON object,我事先知道它會是什么樣子。
[ // ... tens of thousands of these
{
"fileSize": 1155624,
"name": "Gyo v1-001.jpg",
"path": "./userdata/expanded/Gyo v01 (2003)"
},
{
"fileSize": 308145,
"name": "Gyo v1-002.jpg",
"path": "./userdata/expanded/Gyo v01 (2003) (Digital)"
}
// ... tens of thousands of these
]
我開始研究 JSON 流,並在那里取得了一些進展,因為我知道如何使用 NodeJS ReadableStream
客戶端。 我知道我可以使用oboe
來解析 JSON stream。
為此,這是我基於 Express 的應用程序中的代碼。
router.route("/getComicCovers").post(async (req: Request, res: Response) => {
typeof req.body.extractionOptions === "object"
? req.body.extractionOptions
: {};
oboe({
url: "http://localhost:3000/api/import/getComicCovers",
method: "POST",
body: {
extractionOptions: req.body.extractionOptions,
walkedFolders: req.body.walkedFolders,
},
}).on("node", ".*", (data) => {
console.log(data);
res.write(JSON.stringify(data));
});
});
這是moleculer
中的端點
getComicCovers: {
rest: "POST /getComicCovers",
params: {
extractionOptions: "object",
walkedFolders: "array",
},
async handler(
ctx: Context < {
extractionOptions: IExtractionOptions;
walkedFolders: IFolderData[];
} >
) {
const comicBooksForImport = await getCovers(
ctx.params.extractionOptions,
ctx.params.walkedFolders
);
// comicBooksForImport is the aforementioned array of objects.
// How do I stream it from here to the Express app object-by-object?
},
},
我的問題是:我如何 stream 這個巨大的 JSON 從 REST 端點到 Express 應用程序,以便我可以在客戶端解析它?
根據@JuanCaicedo 的建議,我使用了socket.io
實現。 我在服務器端和客戶端都設置了它。
但是,我確實對這段代碼有疑問
map(
walkedFolders,
async (folder, idx) => {
let foo = await extractArchive(
extractionOptions,
folder
);
let fo =
new JsonStreamStringify({
foo,
});
fo.pipe(res);
if (
+idx ===
walkedFolders.length - 1
) {
res.end();
}
}
);
我收到Error [ERR_STREAM_WRITE_AFTER_END]: write after end
錯誤。 我知道發生這種情況是因為響應在下一次迭代嘗試 pipe 更新值foo
(這是一個流)到響應之前終止。
我該如何解決這個問題?
您是在尋求一般方法建議,還是尋求對您擁有的特定解決方案的支持?
如果是第一個,那么我認為在服務器和客戶端之間進行通信的最佳選擇是通過 websockets,也許使用Socket.io 之類的東西。 長壽命的連接將在這里為您提供很好的服務,因為傳輸所有數據需要很長時間。
然后,您可以隨時將數據從服務器發送到客戶端。 此時,您可以將服務器上的數據讀取為 node.js stream 並一次發出一個數據。
使用 Oboe 並在每個節點上寫入響應的問題在於它需要長時間運行的響應,並且在您發送所有數據之前連接很可能會中斷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.