Deno.serve():原生 HTTP API
Deno 2 提供了简洁的内置 Deno.serve() API,基于 Web 标准的 Request/Response 模式,无需任何第三方框架即可构建 HTTP 服务器:
// server.ts — 最简单的 HTTP 服务器
Deno.serve((req: Request) => {
return new Response("Hello, Deno 2!");
});
// 指定端口和主机
Deno.serve({ port: 8080, hostname: "0.0.0.0" }, (req) => {
return new Response("Custom port");
});
// 带生命周期回调
Deno.serve({
port: 8000,
onListen({ hostname, port }) {
console.log(`Server ready: http://${hostname}:${port}`);
},
}, (req) => new Response("OK"));
手动路由
不依赖框架,用原生 URL 和条件判断实现路由:
const handler = async (req: Request): Promise<Response> => {
const url = new URL(req.url);
const { pathname } = url;
const method = req.method;
// GET /
if (method === "GET" && pathname === "/") {
return Response.json({ message: "Deno API", version: "2.0" });
}
// GET /api/users
if (method === "GET" && pathname === "/api/users") {
const page = Number(url.searchParams.get("page")) || 1;
return Response.json({ page, users: [] });
}
// GET /api/users/:id(用正则提取参数)
const userMatch = pathname.match(/^\/api\/users\/(\d+)$/);
if (userMatch && method === "GET") {
const id = Number(userMatch[1]);
return Response.json({ id, name: "Alice" });
}
// POST /api/users
if (method === "POST" && pathname === "/api/users") {
const body = await req.json();
return Response.json({ id: Date.now(), ...body }, { status: 201 });
}
return new Response("Not Found", { status: 404 });
};
Deno.serve(handler);
Hono 框架:推荐的 Deno 框架
Hono 是一个零依赖、超轻量的 Web 框架,原生支持 Deno、Node.js、Bun、Cloudflare Workers 等多种运行时。在 Deno 中使用 Hono 是目前最主流的选择:
// deno.json
{
"imports": {
"hono": "npm:hono@^4.0.0",
"hono/middleware": "npm:hono/middleware"
}
}
// app.ts — Hono 框架示例
import { Hono } from "hono";
import { cors } from "npm:hono/cors";
import { logger } from "npm:hono/logger";
import { zValidator } from "npm:@hono/zod-validator";
import { z } from "npm:zod";
const app = new Hono();
// 全局中间件
app.use("*", logger());
app.use("*", cors({ origin: "https://yourdomain.com" }));
// 路由定义
app.get("/", (c) => c.json({ message: "Deno + Hono" }));
// 路径参数
app.get("/users/:id", (c) => {
const id = c.req.param("id");
return c.json({ id, name: "Alice" });
});
// Zod 验证
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
app.post("/users", zValidator("json", createUserSchema), (c) => {
const data = c.req.valid("json");
return c.json({ id: Date.now(), ...data }, 201);
});
// 错误处理
app.onError((err, c) => {
console.error(err);
return c.json({ error: err.message }, 500);
});
Deno.serve(app.fetch);
中间件模式
// 自定义中间件:JWT 认证
const authMiddleware = async (c: Context, next: Next) => {
const auth = c.req.header("Authorization");
if (!auth?..startsWith("Bearer ")) {
return c.json({ error: "Unauthorized" }, 401);
}
// 验证 token...
c.set("userId", "123");
await next();
};
// 挂载到特定路由组
const api = app.basePath("/api");
api.use("*", authMiddleware);
api.get("/profile", (c) => {
const userId = c.get("userId");
return c.json({ userId });
});
WebSocket 服务器
Deno 原生支持 WebSocket 升级,无需任何第三方库:
// websocket.ts — 原生 WebSocket 聊天室
const clients = new Set<WebSocket>();
Deno.serve((req) => {
// WebSocket 升级
if (req.headers.get("upgrade") === "websocket") {
const { socket, response } = Deno.upgradeWebSocket(req);
socket.addEventListener("open", () => {
clients.add(socket);
console.log(`连接数: ${clients.size}`);
});
socket.addEventListener("message", ({ data }) => {
// 广播给所有客户端
for (const client of clients) {
if (client.readyState === WebSocket.OPEN) {
client.send(`[广播] ${data}`);
}
}
});
socket.addEventListener("close", () => {
clients.delete(socket);
});
return response;
}
return new Response("Not a WebSocket request", { status: 400 });
});
实战:不依赖框架的 RESTful API
// rest-api.ts — 完整 CRUD API(无框架)
interface Todo { id: number; text: string; done: boolean; }
const todos = new Map<number, Todo>();
let nextId = 1;
function json(data: unknown, status = 200) {
return Response.json(data, {
status,
headers: { "Access-Control-Allow-Origin": "*" },
});
}
Deno.serve(async (req) => {
const { pathname } = new URL(req.url);
const idMatch = pathname.match(/^\/todos\/(\d+)$/);
if (pathname === "/todos") {
if (req.method === "GET") {
return json([...todos.values()]);
}
if (req.method === "POST") {
const { text } = await req.json();
const todo: Todo = { id: nextId++, text, done: false };
todos.set(todo.id, todo);
return json(todo, 201);
}
}
if (idMatch) {
const id = Number(idMatch[1]);
if (req.method === "GET") {
const todo = todos.get(id);
return todo ? json(todo) : json({ error: "Not found" }, 404);
}
if (req.method === "PATCH") {
const todo = todos.get(id);
if (!todo) return json({ error: "Not found" }, 404);
const patch = await req.json();
todos.set(id, { ...todo, ...patch });
return json(todos.get(id));
}
if (req.method === "DELETE") {
todos.delete(id);
return new Response(null, { status: 204 });
}
}
return json({ error: "Not Found" }, 404);
});
// deno run --allow-net rest-api.ts
本章小结:Deno.serve() 基于 Web 标准 Request/Response,是 Deno 最简洁的 HTTP API。对于生产项目,推荐使用 Hono 框架——它轻量、类型安全、支持 Zod 验证,且与 Deno Deploy 完美配合。WebSocket 通过 Deno.upgradeWebSocket() 原生支持,无需第三方库。