在本章中,我们将学习如何使用 Deno 实现基本的 CRUD (创建、读取、更新和删除) 操作。这些操作是任何 Web 应用程序的核心部分,因此理解它们对于构建功能丰富的应用程序至关重要。
准备工作
首先,我们需要安装 Deno 和一些必要的依赖项。假设你已经安装了 Deno,请确保你的环境版本是最新的。你可以通过运行以下命令来检查 Deno 的版本:
deno --version
接下来,我们将使用 deno KV 来存储数据。这是一个简单的键值对存储系统,非常适合用于演示目的。首先,我们需要初始化一个新的 Deno 项目,并添加必要的权限。
创建一个新文件夹并进入该文件夹:
mkdir deno-crud && cd deno-crud
然后,初始化一个新的 Deno 项目:
deno task init
打开 deno.json 文件,添加 KV 存储所需的权限:
{
"tasks": {
"start": "deno run --allow-net --allow-read --allow-write --allow-env --unstable mod.ts"
}
}确保你的 Deno 版本支持 --unstable 参数,因为 deno kv 目前还处于实验性阶段。
创建数据
我们将实现一个简单的 API 来创建新条目。首先,在项目根目录下创建一个名为 mod.ts 的文件。这个文件将包含我们的主要逻辑。
在 mod.ts 中,我们首先需要引入 Deno 的 KV API:
import { serve } from "https://deno.land/std@0.158.0/http/server.ts";
import { kv } from "https://deno.land/x/kv/mod.ts";接下来,我们将定义一个处理 POST 请求的函数来创建新条目。这里我们假设我们要存储的是用户信息:
// www.javascriptcn.com code example
async function createUser(req: Request): Promise<Response> {
const user = await req.json();
const id = crypto.randomUUID();
await kv.atomic()
.set(["users", id], user)
.commit();
return new Response(JSON.stringify({ id, ...user }), {
status: 201,
headers: { "Content-Type": "application/json" },
});
}在这个函数中,我们首先从请求体中解析出用户数据,然后生成一个唯一的 ID,并使用 kv.atomic().set() 方法将用户信息保存到 KV 存储中。最后,返回一个带有创建成功状态码的响应。
读取数据
接下来,让我们实现读取操作。这包括获取单个用户信息以及列出所有用户信息的功能。
获取单个用户信息
为了获取特定用户的详细信息,我们可以定义如下函数:
// www.javascriptcn.com code example
async function getUser(req: Request): Promise<Response> {
const url = new URL(req.url);
const id = url.searchParams.get("id");
if (!id) {
return new Response("ID is required", { status: 400 });
}
const user = await kv.get<User>(["users", id]);
if (!user.value) {
return new Response("User not found", { status: 404 });
}
return new Response(JSON.stringify(user.value), {
headers: { "Content-Type": "application/json" },
});
}这里我们从 URL 查询参数中获取用户 ID,然后尝试从 KV 存储中获取对应的用户信息。如果找不到用户,则返回 404 错误;否则,返回用户信息。
列出所有用户信息
要列出所有用户信息,可以定义以下函数:
async function listUsers(): Promise<Response> {
const users = await kv.list<User>({ prefix: ["users"] });
return new Response(JSON.stringify(users.values.map((v) => v.value)), {
headers: { "Content-Type": "application/json" },
});
}此函数遍历所有以 "users" 开头的键值对,并返回一个包含所有用户信息的 JSON 响应。
更新数据
更新操作允许我们修改已存在的用户信息。我们可以定义一个类似于 updateUser 的函数来处理 PUT 请求:
// www.javascriptcn.com code example
async function updateUser(req: Request): Promise<Response> {
const url = new URL(req.url);
const id = url.searchParams.get("id");
const updatedUser = await req.json();
if (!id) {
return new Response("ID is required", { status: 400 });
}
const user = await kv.get<User>(["users", id]);
if (!user.value) {
return new Response("User not found", { status: 404 });
}
await kv.atomic()
.set(["users", id], { ...user.value, ...updatedUser })
.commit();
return new Response(JSON.stringify({ id, ...updatedUser }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}这个函数首先检查是否提供了用户 ID,然后尝试获取现有用户信息。如果找到了用户,它将合并传入的新数据与旧数据,并更新 KV 存储中的记录。
删除数据
最后,我们需要实现删除功能。这可以通过一个简单的 DELETE 请求处理器来完成:
// www.javascriptcn.com code example
async function deleteUser(req: Request): Promise<Response> {
const url = new URL(req.url);
const id = url.searchParams.get("id");
if (!id) {
return new Response("ID is required", { status: 400 });
}
const user = await kv.get<User>(["users", id]);
if (!user.value) {
return new Response("User not found", { status: 404 });
}
await kv.delete(["users", id]);
return new Response("User deleted", { status: 200 });
}这个函数同样需要用户提供用户 ID。如果找到对应用户,则将其从 KV 存储中删除。
路由配置
现在我们已经有了所有的 CRUD 操作函数,接下来我们需要为这些操作配置路由。回到 mod.ts 文件,我们可以设置如下路由:
// www.javascriptcn.com code example
const s = serve({ port: 8000 });
for await (const req of s) {
try {
const { pathname, searchParams } = new URL(req.url);
switch (pathname) {
case "/users":
if (req.method === "POST") {
req.body = req.body?.text() ? await req.body.text() : "";
const user = JSON.parse(req.body);
const response = await createUser(req);
await req.respond(response);
} else if (req.method === "GET") {
const response = await listUsers();
await req.respond(response);
}
break;
case "/user":
if (req.method === "GET") {
const response = await getUser(req);
await req.respond(response);
} else if (req.method === "PUT") {
req.body = req.body?.text() ? await req.body.text() : "";
const updatedUser = JSON.parse(req.body);
const response = await updateUser(req);
await req.respond(response);
} else if (req.method === "DELETE") {
const response = await deleteUser(req);
await req.respond(response);
}
break;
default:
await req.respond({ status: 404 });
}
} catch (err) {
console.error(err);
await req.respond({ status: 500 });
}
}以上代码设置了基本的路由规则,根据不同的 HTTP 方法和路径执行相应的 CRUD 操作。
测试
现在你可以启动服务器并测试这些功能了:
deno task start
使用 Postman 或其他工具进行测试,确保每个 CRUD 操作都能按预期工作。
这就是使用 Deno 实现基本 CRUD 操作的完整示例。希望这个教程对你有所帮助!