跳至主要內容

如何將 Redis 與 Deno 搭配使用

Redis 是一個記憶體內資料儲存,可用於快取、訊息代理或串流資料。

在此處檢視原始程式碼。

我們將在此設定 Redis,以快取來自 API 呼叫的資料,以加速後續對該資料的任何要求。我們將

  • 設定 Redis 伺服器端程式,以儲存來自每個 API 呼叫的資料
  • 設定 Deno 伺服器,以便我們可以輕鬆要求特定資料
  • 在伺服器處理常式中呼叫 Github API,以在第一次要求時取得資料
  • 在每個後續要求中從 Redis 提供資料

我們可以在單一檔案中執行此操作,main.ts

連線至 Redis 伺服器端程式

我們需要兩個模組。第一個是 Deno 伺服器。我們將使用它來取得使用者的資訊,以查詢我們的 API。第二個是 Redis。我們可以使用 npm: 修改器來取得 Redis 的節點套件

import { createClient } from "npm:redis@^4.5";

我們使用 createClient 建立 Redis 伺服器端程式,並連線至我們的本機 Redis 伺服器

// make a connection to the local instance of redis
const client = createClient({
url: "redis://127.0.0.1:6379",
});

await client.connect();

您也可以個別在此 組態 物件中設定主機、使用者、密碼和連接埠。

設定伺服器

我們的伺服器將作為 Github API 的包裝器。用戶端可以在 URL 路徑名稱中使用 Github 使用者名稱呼叫我們的伺服器,例如 https://127.0.0.1:3000/{username}

解析路徑名稱和呼叫 Github API 將在我們伺服器的處理函式中進行。我們移除開頭的斜線,這樣我們就可以得到一個變數,可以作為使用者名稱傳遞給 Github API。然後我們會將回應傳回給使用者。

Deno.serve({ port: 3000 }, async (req) => {
const { pathname } = new URL(req.url);
// strip the leading slash
const username = pathname.substring(1);
const resp = await fetch(`https://api.github.com/users/${username}`);
const user = await resp.json();
return new Response(JSON.stringify(user), {
headers: {
"content-type": "application/json",
},
});
});

我們將使用以下指令執行此操作:

deno run --allow-net main.ts

如果我們在 Postman 中前往 https://127.0.0.1:3000/ry,我們將取得 Github 回應

uncached-redis-body.png

讓我們使用 Redis 快取此回應。

檢查快取

一旦我們從 Github API 取得回應,我們可以使用 client.set 將其快取在 Redis 中,其中我們的使用者名稱為金鑰,使用者物件為值

await client.set(username, JSON.stringify(user));

下次我們要求相同的使用者名稱時,我們可以使用 client.get 取得快取的使用者

const cached_user = await client.get(username);

如果金鑰不存在,這將傳回 null。因此我們可以在一些流程控制中使用它。當我們取得使用者名稱時,我們會先檢查快取中是否已經有該使用者。如果有的話,我們會提供快取的結果。如果沒有,我們會呼叫 Github API 取得使用者,快取它,然後提供 API 結果。在兩種情況下,我們都會新增一個自訂標頭,以顯示我們提供的版本

const server = new Server({
handler: async (req) => {
const { pathname } = new URL(req.url);
// strip the leading slash
const username = pathname.substring(1);
const cached_user = await client.get(username);
if (cached_user) {
return new Response(cached_user, {
headers: {
"content-type": "application/json",
"is-cached": "true",
},
});
} else {
const resp = await fetch(`https://api.github.com/users/${username}`);
const user = await resp.json();
await client.set(username, JSON.stringify(user));
return new Response(JSON.stringify(user), {
headers: {
"content-type": "application/json",
"is-cached": "false",
},
});
}
},

port: 3000,
});

server.listenAndServe();

第一次執行此操作會提供與上述相同的回應,我們會看到 is-cached 標頭設定為 false

uncached-redis-header.png

但再次使用相同的使用者名稱呼叫,我們會取得快取的結果。主體是相同的

cached-redis-body.png

但標頭顯示我們有快取

cached-redis-header.png

我們也可以看到回應快了約 200 毫秒!

你可以查看 這裡 的 Redis 文件和 這裡 的 Redis 節點套件。