跳至主要內容

將 Webhook 處理卸載到佇列

在網路應用程式中,通常需要將非同步任務的處理卸載到佇列,而客戶端不需要立即回應。這麼做可以讓您的網路應用程式保持快速且有回應,而不是佔用寶貴的資源來等待執行時間長的程序完成。

您可能想要部署此技術的一個範例是在 處理網路掛鉤 時。在從不需要回應的非人類客戶端收到網路掛鉤要求後,您可以將該工作卸載到佇列,以便更有效率地處理。

在本教學課程中,我們將向您展示在 處理 GitHub 儲存庫的網路掛鉤要求 時如何執行此技術。

在遊樂場中嘗試

✏️ 查看此遊樂場,它實作了 GitHub 儲存庫網路掛鉤處理程式

使用 Deno Deploy 遊樂場,您可以立即部署您自己的 GitHub 網路掛鉤處理程式,它同時使用佇列和 Deno KV。我們將在稍後逐步說明此程式碼的功能。

設定儲存庫的 GitHub 網路掛勾

若要嘗試您剛在遊樂場中啟動的網路掛勾,請為您控制的 GitHub 儲存庫設定新的網路掛勾設定。您可以在儲存庫的「設定」中找到網路掛勾設定。

configure a github webhook

程式碼演練

我們的網路掛勾處理函式相對簡單,不含註解時,程式碼總共只有 23 行。它會連線到 Deno KV 資料庫,設定佇列監聽器來處理傳入訊息,並設定一個使用 Deno.serve 的簡單伺服器,回應傳入的網路掛勾要求。

請搭配以下註解閱讀,了解每一步驟的運作方式。

server.ts
// Get a handle for a Deno KV database instance. KV is built in to the Deno
// runtime, and is available with zero config both locally and on Deno Deploy
const kv = await Deno.openKv();

// Set up a listener that will handle work that is offloaded from our server.
// In this case, it's just going to add incoming webhook payloads to a KV
// database, with a timestamp.
kv.listenQueue(async (message) => {
await kv.set(["github", Date.now()], message);
});

// This is a simple HTTP server that will handle incoming POST requests from
// GitHub webhooks.
Deno.serve(async (req: Request) => {
if (req.method === "POST") {
// GitHub sends webhook requests as POST requests to your server. You can
// configure GitHub to send JSON in the POST body, which you can then parse
// from the request object.
const payload = await req.json();
await kv.enqueue(payload);
return new Response("", { status: 200 });
} else {
// If the server is handling a GET request, this will just list out all the
// webhook events that have been recorded in our KV database.
const iter = kv.list<string>({ prefix: ["github"] });
const github = [];
for await (const res of iter) {
github.push({
timestamp: res.key[1],
payload: res.value,
});
}
return new Response(JSON.stringify(github, null, 2));
}
});