使用 TypeScript 构建 API 服务器
视频描述 跳转到标题
使用轻量级的 Hono 框架(Express 的精神继承者)构建一个 RESTful API 服务器,该服务器支持使用数据库进行 CRUD 操作。
文字记录和代码 跳转到标题
如果您过去曾参与过 Node 项目,您可能使用过 Express 来设置 Web 服务器或托管 API。 让我们看看如何使用 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);