使用 TypeScript 建構 API 伺服器
影片描述 跳到標題
使用輕量級的 Hono 框架(Express 的精神繼承者)來建構支援資料庫 CRUD 操作的 RESTful API 伺服器。
文字稿和程式碼 跳到標題
如果您過去曾參與 Node 專案,您可能使用過 Express 來設定 Web 伺服器或託管 API。讓我們看看如何使用 Hono 這個小巧簡單的框架來做類似的事情,Hono 可以與任何執行階段一起使用,但我們將與 Deno 一起使用。基本 Hono 設定
我們將使用 JSR 將 Hono 新增到我們的專案中
deno add jsr:@hono/hono
然後這將被新增到 deno.json 檔案中。
然後在我們的主檔案中,我們將建立基本的 Hono 設定。
import { Hono } from "@hono/hono";
const app = new Hono();
app.get("/", (c) => {
return c.text("Hello from the Trees!");
});
Deno.serve(app.fetch);
讓我們執行 deno run --allow-net main.ts
,我們將在瀏覽器中的 localhost:8000
看到它。
CRUD 操作 跳到標題
現在我們已經使用 Hono 設定了簡單的伺服器,我們可以開始建構我們的資料庫。
我們將在此使用 localStorage,但請記住,您可以將任何持久性資料儲存與 Deno 一起使用 - postgres、sql - 任何您喜歡儲存資料的地方。
讓我們從建立一些資料的容器開始。我們將從描述樹狀結構類型的介面開始
interface Tree {
id: string;
species: string;
age: number;
location: string;
}
然後我們將建立一些資料
const oak: Tree = {
id: "3",
species: "oak",
age: 3,
location: "Jim's Park",
};
然後我們將建立一些輔助函式,這些函式將幫助我們與 localStorage 互動
const setItem = (key: string, value: Tree) => {
localStorage.setItem(key, JSON.stringify(value));
};
const getItem = (key: string): Tree | null => {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : null;
};
現在讓我們使用它們
setItem(`trees_${oak.id}`, oak);
const newTree = getItem(`trees_${oak.id}`);
console.log(newTree);
deno --allow-net main.ts
setItem
正在新增樹狀結構- 您也可以使用
setItem
來更新記錄 -- 如果金鑰已存在,則值將會更新
const oak: Tree = {
id: "3",
species: "oak",
age: 4,
location: "Jim's Park",
};
localStorage.setItem(`trees_${oak.id}`, JSON.stringify(oak));
好的,現在讓我們使用 Hono 的路由來建立一些 REST API 路由,現在我們了解如何使用這些資料庫方法
app.post("/trees", async (c) => {
const { id, species, age, location } = await c.req.json();
const tree: Tree = { id, species, age, location };
setItem(`trees_${id}`, tree);
return c.json({
message: `We just added a ${species} tree!`,
});
});
為了測試這個,我們將傳送 curl 請求
curl -X POST https://127.0.0.1:8000/trees \
-H "Content-Type: application/json" \
-d '{"id": "2", "species": "Willow", "age": 100, "location": "Juniper Park"}'
為了證明我們建立了該樹狀結構,讓我們依其 ID 取得資料
app.get("/trees/:id", async (c) => {
const id = c.req.param("id");
const tree = await kv.get(["trees", id]);
if (!tree.value) {
return c.json({ message: "Tree not found" }, 404);
}
return c.json(tree.value);
});
為了測試這一點,讓我們為資料執行 curl 請求
curl https://127.0.0.1:8000/trees/1
或者您可以在瀏覽器中前往它:https://127.0.0.1:8000/trees/1
我們當然可以更新樹狀結構。有點像以前一樣,但我們將為此建立一個路由
app.put("/trees/:id", (c) => {
const id = c.req.param("id");
const { species, age, location } = c.req.json();
const updatedTree: Tree = { id, species, age, location };
setItem(`trees_${id}`, updatedTree);
return c.json({
message: `Tree has relocated to ${location}!`,
});
});
我們將變更位置,因為我們將把這棵樹狀結構 PUT 到其他地方
curl -X PUT https://127.0.0.1:8000/trees/1 \
-H "Content-Type: application/json" \
-d '{"species": "Oak", "age": 8, "location": "Theft Park"}'
最後,如果我們想要刪除樹狀結構,我們可以使用 Hono delete 函式。
const deleteItem = (key: string) => {
localStorage.removeItem(key);
};
app.delete("/trees/:id", (c) => {
const id = c.req.param("id");
deleteItem(`trees_${id}`);
return c.json({
message: `Tree ${id} has been cut down!`,
});
});
我們已將 Deno 與 Hono 結合使用,為我們的樹狀結構資料建構了一個小型 REST API。如果我們想要部署這個,我們可以,並且我們可以零設定部署到 Deno deploy。
您可以將其部署到任何雲端 VPS,例如 AWS、GCP、Digital Ocean,使用 官方 Docker 映像
完整程式碼範例 跳到標題
import { Hono } from "@hono/hono";
const app = new Hono();
interface Tree {
id: string;
species: string;
age: number;
location: string;
}
const setItem = (key: string, value: Tree) => {
localStorage.setItem(key, JSON.stringify(value));
};
const getItem = (key: string): Tree | null => {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : null;
};
const deleteItem = (key: string) => {
localStorage.removeItem(key);
};
const oak: Tree = {
id: "3",
species: "oak",
age: 3,
location: "Jim's Park",
};
setItem(`trees_${oak.id}`, oak);
const newTree = getItem(`trees_${oak.id}`);
console.log(newTree);
app.get("/", (c) => {
return c.text("Hello from the Trees!");
});
app.post("/trees", async (c) => {
const { id, species, age, location } = await c.req.json();
const tree: Tree = { id, species, age, location };
setItem(`trees_${id}`, tree);
return c.json({
message: `We just added a ${species} tree!`,
});
});
app.get("/trees/:id", async (c) => {
const id = await c.req.param("id");
const tree = getItem(`trees_${id}`);
if (!tree) {
return c.json({ message: "Tree not found" }, 404);
}
return c.json(tree);
});
app.put("/trees/:id", async (c) => {
const id = c.req.param("id");
const { species, age, location } = await c.req.json();
const updatedTree: Tree = { id, species, age, location };
setItem(`trees_${id}`, updatedTree);
return c.json({
message: `Tree has relocated to ${location}!`,
});
});
app.delete("/trees/:id", (c) => {
const id = c.req.param("id");
deleteItem(`trees_${id}`);
return c.json({
message: `Tree ${id} has been cut down!`,
});
});
Deno.serve(app.fetch);