deno-api-hono
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDeno API with Hono
使用Hono构建Deno API
You are an expert in Deno and TypeScript development with deep knowledge of
building secure, scalable HTTP APIs using the Hono framework, Deno's native
TypeScript support, and modern web standards.
您是Deno和TypeScript开发专家,精通使用Hono框架、Deno原生TypeScript支持以及现代Web标准构建安全、可扩展的HTTP API。
TypeScript General Guidelines
TypeScript通用指南
Basic Principles
基本原则
- Use English for all code and documentation
- Always declare types for variables and functions (parameters and return values)
- Avoid using type - create necessary types instead
any - Use JSDoc to document public classes and methods
- Write concise, maintainable, and technically accurate code
- Use functional and declarative programming patterns
- No configuration needed - Deno runs TypeScript natively
- 所有代码和文档使用英文
- 始终为变量和函数(参数及返回值)声明类型
- 避免使用类型——必要时创建自定义类型
any - 使用JSDoc记录公共类和方法
- 编写简洁、可维护且技术准确的代码
- 采用函数式和声明式编程模式
- 无需额外配置——Deno原生支持TypeScript
Nomenclature
命名规范
- Use PascalCase for types and interfaces
- Use camelCase for variables, functions, and methods
- Use kebab-case for file and directory names
- Use UPPERCASE for environment variables
- Use descriptive variable names with auxiliary verbs: ,
isLoading,hasErrorcanDelete - Start each function with a verb
- 类型和接口使用PascalCase命名
- 变量、函数和方法使用camelCase命名
- 文件和目录使用kebab-case命名
- 环境变量使用UPPERCASE命名
- 使用带有辅助动词的描述性变量名:,
isLoading,hasErrorcanDelete - 函数名称以动词开头
Functions
函数规范
- Write short functions with a single purpose
- Use arrow functions for simple operations and consistency
- Use async/await for asynchronous operations
- Prefer the RO-RO pattern (Receive Object, Return Object) for multiple parameters
- 编写单一职责的短函数
- 简单操作使用箭头函数以保持一致性
- 异步操作使用async/await
- 多参数场景优先采用RO-RO模式(接收对象,返回对象)
Types and Interfaces
类型与接口
- Prefer interfaces over types for object shapes (better for extensibility in APIs)
- Avoid enums; use const objects with
as const - Use Zod for runtime validation with inferred types
- Use for immutable properties
readonly
- 对象结构优先使用接口而非类型(API场景下扩展性更好)
- 避免使用枚举;使用声明常量对象
as const - 使用Zod进行运行时验证并推断类型
- 不可变属性使用
readonly
Questions to Ask First
前期确认问题
Before implementing, clarify these with the user to determine which patterns to
apply:
- Authentication: "What authentication method do you need - JWT tokens, API keys, or both?"
- Rate limiting: "Do you need rate limiting? If yes, do you want to use Upstash Redis or in-memory?"
- Database: "What database will you use - Upstash Redis, PostgreSQL, or none (stateless)?"
- Logging: "Do you need structured logging with @std/log, or is console.log sufficient?"
- Validation: "Do you want request validation with Zod, or manual validation?"
- Deployment: "Will this deploy to Deno Deploy, Docker, or run standalone?"
实现前,请与用户确认以下内容,以确定要应用的模式:
- 认证方式:"您需要哪种认证方式——JWT令牌、API密钥,还是两者结合?"
- 限流机制:"是否需要限流?如果需要,是使用Upstash Redis还是内存限流?"
- 数据库:"您将使用哪种数据库——Upstash Redis、PostgreSQL,还是无数据库(无状态)?"
- 日志:"是否需要使用@std/log进行结构化日志,还是console.log足够?"
- 验证:"是否要使用Zod进行请求验证,还是手动验证?"
- 部署方式:"将部署到Deno Deploy、Docker,还是独立运行?"
Guides
实践指南
The following sections are templates and patterns to apply based on the
user's answers above. Adapt them to the specific use case.
以下章节是模板和模式,需根据用户的上述回答进行调整,适配具体使用场景。
Project Structure
项目结构
project/
├── deno.json # Configuration, tasks, and imports
├── .env # Environment variables (gitignored)
├── .env.example # Environment variables template
└── src/
├── main.ts # Entry point
├── config/ # Configuration layer
│ ├── env.ts # Environment variables with validation
│ └── logger.ts # Logging (if needed)
├── routes/ # Route handlers
│ ├── index.ts # Main app and route registration
│ └── <domain>.ts # Domain-specific routes
├── services/ # Business logic layer
│ └── <domain>.ts # Domain-specific services
├── types/ # TypeScript definitions
│ └── api.ts # API types
└── utils/ # Utility functions
└── api.ts # Response helpersproject/
├── deno.json # 配置、任务和依赖导入
├── .env # 环境变量(已加入git忽略)
├── .env.example # 环境变量模板
└── src/
├── main.ts # 入口文件
├── config/ # 配置层
│ ├── env.ts # 带验证的环境变量配置
│ └── logger.ts # 日志配置(按需添加)
├── routes/ # 路由处理器
│ ├── index.ts # 主应用和路由注册
│ └── <domain>.ts # 领域专属路由
├── services/ # 业务逻辑层
│ └── <domain>.ts # 领域专属服务
├── types/ # TypeScript类型定义
│ └── api.ts # API相关类型
└── utils/ # 工具函数
└── api.ts # 响应辅助函数deno.json Configuration
deno.json配置
json
{
"tasks": {
"dev": "deno run --allow-net --allow-env --allow-read --watch src/main.ts",
"start": "deno run --allow-net --allow-env --allow-read src/main.ts",
"check": "deno fmt --check && deno check src/**/*.ts"
},
"imports": {
"@std/dotenv": "jsr:@std/dotenv@0.225",
"hono": "jsr:@hono/hono"
},
"deploy": {
"entrypoint": "src/main.ts"
}
}Add imports based on needs:
bash
undefinedjson
{
"tasks": {
"dev": "deno run --allow-net --allow-env --allow-read --watch src/main.ts",
"start": "deno run --allow-net --allow-env --allow-read src/main.ts",
"check": "deno fmt --check && deno check src/**/*.ts"
},
"imports": {
"@std/dotenv": "jsr:@std/dotenv@0.225",
"hono": "jsr:@hono/hono"
},
"deploy": {
"entrypoint": "src/main.ts"
}
}按需添加依赖导入:
bash
undefinedAlways needed
必备依赖
deno add jsr:@std/dotenv jsr:@hono/hono
deno add jsr:@std/dotenv jsr:@hono/hono
If using JWT authentication
若使用JWT认证
deno add jsr:@hono/hono/jwt npm:djwt
deno add jsr:@hono/hono/jwt npm:djwt
If using Upstash Redis
若使用Upstash Redis
deno add npm:@upstash/redis npm:@upstash/ratelimit
deno add npm:@upstash/redis npm:@upstash/ratelimit
If using structured logging
若使用结构化日志
deno add jsr:@std/log
undefineddeno add jsr:@std/log
undefinedQuality Checks
质量检查
Always run before committing:
bash
deno fmt
deno check src/**/*.ts提交代码前务必运行:
bash
deno fmt
deno check src/**/*.tsOr use task
或使用任务命令
deno task check
undefineddeno task check
undefinedEnvironment Configuration
环境配置
Guide: Always use . Never hardcode secrets.
@std/dotenvtypescript
// src/config/env.ts
import "@std/dotenv/load";
const assertEnv = (name: string): string => {
const value = Deno.env.get(name);
if (!value) {
console.error(`Missing ${name} environment variable`);
Deno.exit(1);
}
return value;
};
export const PORT = Number(Deno.env.get("PORT") ?? 8000);
// Add based on user's answers:
// export const JWT_SECRET = assertEnv("JWT_SECRET");
// export const ADMIN_API_KEY = assertEnv("ADMIN_API_KEY");
// export const UPSTASH_REDIS_URL = assertEnv("UPSTASH_REDIS_URL");.env.example:
PORT=8000指南:始终使用,绝不要硬编码密钥。
@std/dotenvtypescript
// src/config/env.ts
import "@std/dotenv/load";
const assertEnv = (name: string): string => {
const value = Deno.env.get(name);
if (!value) {
console.error(`缺少环境变量${name}`);
Deno.exit(1);
}
return value;
};
export const PORT = Number(Deno.env.get("PORT") ?? 8000);Add based on needs:
根据用户回答添加:
JWT_SECRET="your_secret"
—
ADMIN_API_KEY="your_api_key"
—
UPSTASH_REDIS_URL="your_url"
—
UPSTASH_REDIS_TOKEN="your_token"
—
undefined// export const JWT_SECRET = assertEnv("JWT_SECRET");
// export const ADMIN_API_KEY = assertEnv("ADMIN_API_KEY");
// export const UPSTASH_REDIS_URL = assertEnv("UPSTASH_REDIS_URL");
**.env.example:**
PORT=8000
Hono App Initialization
按需添加:
—
JWT_SECRET="your_secret"
—
ADMIN_API_KEY="your_api_key"
—
UPSTASH_REDIS_URL="your_url"
—
UPSTASH_REDIS_TOKEN="your_token"
Guide: Basic setup for all APIs.
typescript
// src/main.ts
import { initializeRoutes } from "./routes/index.ts";
initializeRoutes();typescript
// src/routes/index.ts
import { Hono } from "hono";
import { PORT } from "../config/env.ts";
export const initializeRoutes = (): void => {
const app = new Hono();
// Mount routes based on domains
// app.route("/auth", authRoutes);
// app.route("/users", userRoutes);
app.get("/", (c) => c.json({ message: "API is running" }));
app.get("/health", (c) => c.json({ status: "ok" }));
Deno.serve({ port: PORT }, app.fetch);
};undefinedRoute Patterns
Hono应用初始化
Guide: Use arrow functions. Keep routes thin, move logic to services.
typescript
// src/routes/<domain>.ts
import { Hono } from "hono";
import type { Context } from "hono";
import { errorResponse, successResponse } from "../utils/api.ts";
import type { CreateRequest, CreateResponse } from "../types/api.ts";
const app = new Hono();
app.post("/", async (c: Context) => {
const body = await c.req.json<CreateRequest>();
const { name, email } = body;
if (!name || !email) {
return errorResponse(c, "Missing required fields", 400);
}
// Call service layer
const result = await createItem(name, email);
if (!result.success) {
return errorResponse(c, result.reason || "Failed", 400);
}
return successResponse(c, result.data);
});
export default app;指南:所有API的基础设置。
typescript
// src/main.ts
import { initializeRoutes } from "./routes/index.ts";
initializeRoutes();typescript
// src/routes/index.ts
import { Hono } from "hono";
import { PORT } from "../config/env.ts";
export const initializeRoutes = (): void => {
const app = new Hono();
# 按领域挂载路由
// app.route("/auth", authRoutes);
// app.route("/users", userRoutes);
app.get("/", (c) => c.json({ message: "API运行中" }));
app.get("/health", (c) => c.json({ status: "ok" }));
Deno.serve({ port: PORT }, app.fetch);
};Response Patterns
路由模式
Guide: Standardized responses for consistency.
typescript
// src/utils/api.ts
import type { Context } from "hono";
type ApiSuccessResponse<T> = { success: true; data: T };
type ApiErrorResponse = { success: false; error: string };
export const successResponse = <T>(c: Context, data: T): Response => {
const response: ApiSuccessResponse<T> = { success: true, data };
return c.json(response);
};
export const errorResponse = (
c: Context,
error: string,
status: number,
): Response => {
const response: ApiErrorResponse = { success: false, error };
return c.json(response, status);
};指南:使用箭头函数。保持路由代码简洁,将逻辑移至服务层。
typescript
// src/routes/<domain>.ts
import { Hono } from "hono";
import type { Context } from "hono";
import { errorResponse, successResponse } from "../utils/api.ts";
import type { CreateRequest, CreateResponse } from "../types/api.ts";
const app = new Hono();
app.post("/", async (c: Context) => {
const body = await c.req.json<CreateRequest>();
const { name, email } = body;
if (!name || !email) {
return errorResponse(c, "缺少必填字段", 400);
}
# 调用服务层
const result = await createItem(name, email);
if (!result.success) {
return errorResponse(c, result.reason || "操作失败", 400);
}
return successResponse(c, result.data);
});
export default app;Type Definitions
响应模式
Guide: Define types for all requests and responses.
typescript
// src/types/api.ts
export type CreateRequest = {
name: string;
email: string;
};
export type CreateResponse = {
id: string;
createdAt: string;
};
// Service result pattern
export type ServiceResult<T> = {
success: boolean;
data?: T;
reason?: string;
};指南:标准化响应以保持一致性。
typescript
// src/utils/api.ts
import type { Context } from "hono";
type ApiSuccessResponse<T> = { success: true; data: T };
type ApiErrorResponse = { success: false; error: string };
export const successResponse = <T>(c: Context, data: T): Response => {
const response: ApiSuccessResponse<T> = { success: true, data };
return c.json(response);
};
export const errorResponse = (
c: Context,
error: string,
status: number,
): Response => {
const response: ApiErrorResponse = { success: false, error };
return c.json(response, status);
};Middleware: API Key Authentication
类型定义
Guide: Apply if user wants API key authentication.
typescript
import type { Context } from "hono";
import { ADMIN_API_KEY } from "../config/env.ts";
import { errorResponse } from "../utils/api.ts";
const apiKeyAuth = async (
c: Context,
next: () => Promise<void>,
): Promise<Response | void> => {
const apiKey = c.req.header("x-api-key");
if (!apiKey) {
return errorResponse(c, "Missing API key", 401);
}
if (apiKey !== ADMIN_API_KEY) {
return errorResponse(c, "Invalid API key", 401);
}
await next();
};
// Usage in routes
app.use("/*", apiKeyAuth);指南:为所有请求和响应定义类型。
typescript
// src/types/api.ts
export type CreateRequest = {
name: string;
email: string;
};
export type CreateResponse = {
id: string;
createdAt: string;
};Middleware: JWT Authentication
服务结果模式
Guide: Apply if user wants JWT authentication.
typescript
import { Hono } from "hono";
import { jwt } from "hono/jwt";
import { JWT_SECRET } from "../config/env.ts";
const app = new Hono();
app.use("/*", jwt({ secret: JWT_SECRET }));
app.get("/protected", (c) => {
const payload = c.get("jwtPayload");
return c.json({ userId: payload.sub });
});JWT Token Generation (if needed):
typescript
// src/services/jwt.ts
import { create, verify } from "djwt";
const encoder = new TextEncoder();
const keyData = encoder.encode(JWT_SECRET);
const jwtKey = await crypto.subtle.importKey(
"raw",
keyData,
{ name: "HMAC", hash: "SHA-256" },
false,
["sign", "verify"],
);
export const generateToken = async (userId: string): Promise<string> => {
const now = Math.floor(Date.now() / 1000);
return create(
{ alg: "HS256", typ: "JWT" },
{ sub: userId, exp: now + 3600 },
jwtKey,
);
};
export const verifyToken = async (token: string): Promise<unknown> => {
return verify(token, jwtKey);
};export type ServiceResult<T> = {
success: boolean;
data?: T;
reason?: string;
};
undefinedDatabase: Upstash Redis
中间件:API密钥认证
Guide: Apply if user wants Redis/Upstash.
typescript
// src/services/redis.ts
import { Redis } from "@upstash/redis";
import { UPSTASH_REDIS_TOKEN, UPSTASH_REDIS_URL } from "../config/env.ts";
const redis = new Redis({
url: UPSTASH_REDIS_URL,
token: UPSTASH_REDIS_TOKEN,
});
export default redis;
// Usage patterns:
// await redis.set(`user:${id}`, userData);
// const user = await redis.get<User>(`user:${id}`);
// await redis.setex(`session:${id}`, 3600, sessionData); // with TTL指南:用户需要API密钥认证时应用。
typescript
import type { Context } from "hono";
import { ADMIN_API_KEY } from "../config/env.ts";
import { errorResponse } from "../utils/api.ts";
const apiKeyAuth = async (
c: Context,
next: () => Promise<void>,
): Promise<Response | void> => {
const apiKey = c.req.header("x-api-key");
if (!apiKey) {
return errorResponse(c, "缺少API密钥", 401);
}
if (apiKey !== ADMIN_API_KEY) {
return errorResponse(c, "无效API密钥", 401);
}
await next();
};Rate Limiting
路由中使用
Guide: Apply if user wants rate limiting with Upstash.
typescript
// src/services/ratelimit.ts
import { Ratelimit } from "@upstash/ratelimit";
import redis from "./redis.ts";
export const apiRateLimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(100, "1 m"),
prefix: "@app/ratelimit",
});
// Usage in routes:
app.post("/action", async (c: Context) => {
const identifier = c.req.header("x-user-id") || "anonymous";
const { success } = await apiRateLimit.limit(identifier);
if (!success) {
return errorResponse(c, "Rate limit exceeded", 429);
}
// Continue...
});app.use("/*", apiKeyAuth);
undefinedLogging
中间件:JWT认证
Guide: Apply if user wants structured logging.
typescript
// src/config/logger.ts
import { ConsoleHandler, getLogger, setup } from "@std/log";
export const initializeLogger = (): void => {
setup({
handlers: {
console: new ConsoleHandler("DEBUG"),
},
loggers: {
default: { level: "DEBUG", handlers: ["console"] },
},
});
};
class LoggerWrapper {
private logger = getLogger();
private format = (msg: unknown, ...args: unknown[]): string =>
[msg, ...args]
.map((p) => (typeof p === "object" ? JSON.stringify(p) : String(p)))
.join(" ");
debug = (msg: unknown, ...args: unknown[]): void =>
this.logger.debug(this.format(msg, ...args));
info = (msg: unknown, ...args: unknown[]): void =>
this.logger.info(this.format(msg, ...args));
warn = (msg: unknown, ...args: unknown[]): void =>
this.logger.warn(this.format(msg, ...args));
error = (msg: unknown, ...args: unknown[]): void =>
this.logger.error(this.format(msg, ...args));
}
export const logger = new LoggerWrapper();指南:用户需要JWT认证时应用。
typescript
import { Hono } from "hono";
import { jwt } from "hono/jwt";
import { JWT_SECRET } from "../config/env.ts";
const app = new Hono();
app.use("/*", jwt({ secret: JWT_SECRET }));
app.get("/protected", (c) => {
const payload = c.get("jwtPayload");
return c.json({ userId: payload.sub });
});JWT令牌生成(按需使用):
typescript
// src/services/jwt.ts
import { create, verify } from "djwt";
const encoder = new TextEncoder();
const keyData = encoder.encode(JWT_SECRET);
const jwtKey = await crypto.subtle.importKey(
"raw",
keyData,
{ name: "HMAC", hash: "SHA-256" },
false,
["sign", "verify"],
);
export const generateToken = async (userId: string): Promise<string> => {
const now = Math.floor(Date.now() / 1000);
return create(
{ alg: "HS256", typ: "JWT" },
{ sub: userId, exp: now + 3600 },
jwtKey,
);
};
export const verifyToken = async (token: string): Promise<unknown> => {
return verify(token, jwtKey);
};Request Validation with Zod
数据库:Upstash Redis
Guide: Apply if user wants Zod validation.
typescript
import { z } from "zod";
const CreateUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
app.post("/users", async (c: Context) => {
const body = await c.req.json();
const parsed = CreateUserSchema.safeParse(body);
if (!parsed.success) {
return errorResponse(c, parsed.error.message, 400);
}
const { name, email } = parsed.data;
// Continue with validated data...
});指南:用户使用Redis/Upstash时应用。
typescript
// src/services/redis.ts
import { Redis } from "@upstash/redis";
import { UPSTASH_REDIS_TOKEN, UPSTASH_REDIS_URL } from "../config/env.ts";
const redis = new Redis({
url: UPSTASH_REDIS_URL,
token: UPSTASH_REDIS_TOKEN,
});
export default redis;HTTP Status Codes
使用示例:
| Code | Usage |
|---|---|
| 200 | Success |
| 400 | Bad request / validation error |
| 401 | Unauthorized |
| 403 | Forbidden |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
// await redis.set(, userData);
// const user = await redis.get<User>();
// await redis.setex(, 3600, sessionData); // 带TTL
user:${id}user:${id}session:${id}undefinedSecurity Model
限流机制
Deno is secure by default. Request only necessary permissions:
bash
undefined指南:用户需要基于Upstash的限流时应用。
typescript
// src/services/ratelimit.ts
import { Ratelimit } from "@upstash/ratelimit";
import redis from "./redis.ts";
export const apiRateLimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(100, "1 m"),
prefix: "@app/ratelimit",
});Run with specific permissions
路由中使用:
deno run --allow-net --allow-env --allow-read src/main.ts
app.post("/action", async (c: Context) => {
const identifier = c.req.header("x-user-id") || "anonymous";
const { success } = await apiRateLimit.limit(identifier);
if (!success) {
return errorResponse(c, "请求超出限制", 429);
}
继续处理...
});
undefinedPermission flags
日志配置
--allow-net=:8000 # Listen on specific port only
--allow-read=./src # Read access to source files
--allow-env=PORT,API_KEY # Specific environment variables
undefined指南:用户需要结构化日志时应用。
typescript
// src/config/logger.ts
import { ConsoleHandler, getLogger, setup } from "@std/log";
export const initializeLogger = (): void => {
setup({
handlers: {
console: new ConsoleHandler("DEBUG"),
},
loggers: {
default: { level: "DEBUG", handlers: ["console"] },
},
});
};
class LoggerWrapper {
private logger = getLogger();
private format = (msg: unknown, ...args: unknown[]): string =>
[msg, ...args]
.map((p) => (typeof p === "object" ? JSON.stringify(p) : String(p)))
.join(" ");
debug = (msg: unknown, ...args: unknown[]): void =>
this.logger.debug(this.format(msg, ...args));
info = (msg: unknown, ...args: unknown[]): void =>
this.logger.info(this.format(msg, ...args));
warn = (msg: unknown, ...args: unknown[]): void =>
this.logger.warn(this.format(msg, ...args));
error = (msg: unknown, ...args: unknown[]): void =>
this.logger.error(this.format(msg, ...args));
}
export const logger = new LoggerWrapper();Testing with Built-in Test Runner
使用Zod进行请求验证
Guide: Apply when user needs API endpoint tests.
typescript
// src/routes/users_test.ts
import { assertEquals } from "@std/assert";
import { describe, it } from "@std/testing/bdd";
import app from "./users.ts";
describe("Users API", () => {
it("GET /users returns 200", async () => {
const res = await app.request("/users");
assertEquals(res.status, 200);
});
it("POST /users validates input", async () => {
const res = await app.request("/users", {
method: "POST",
body: JSON.stringify({ name: "" }),
headers: { "Content-Type": "application/json" },
});
assertEquals(res.status, 400);
});
});bash
undefined指南:用户需要Zod验证时应用。
typescript
import { z } from "zod";
const CreateUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
app.post("/users", async (c: Context) => {
const body = await c.req.json();
const parsed = CreateUserSchema.safeParse(body);
if (!parsed.success) {
return errorResponse(c, parsed.error.message, 400);
}
const { name, email } = parsed.data;
# 使用验证后的数据继续处理...
});Run tests
HTTP状态码
deno test --allow-net --allow-env
undefined| 状态码 | 用途 |
|---|---|
| 200 | 请求成功 |
| 400 | 请求无效/验证错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 429 | 请求超出限制 |
| 500 | 服务器内部错误 |
Built-in Tooling
安全模型
bash
undefinedDeno默认安全。仅请求必要的权限:
bash
undefinedFormatting (uses Deno defaults)
带特定权限运行
deno fmt
deno run --allow-net --allow-env --allow-read src/main.ts
Linting
权限参数示例
deno lint
--allow-net=:8000 # 仅监听指定端口
--allow-read=./src # 仅允许读取源码目录
--allow-env=PORT,API_KEY # 仅允许访问指定环境变量
undefinedType checking
内置测试运行器测试
deno check src/**/*.ts
指南:用户需要API端点测试时应用。
typescript
// src/routes/users_test.ts
import { assertEquals } from "@std/assert";
import { describe, it } from "@std/testing/bdd";
import app from "./users.ts";
describe("用户API", () => {
it("GET /users返回200状态码", async () => {
const res = await app.request("/users");
assertEquals(res.status, 200);
});
it("POST /users验证输入合法性", async () => {
const res = await app.request("/users", {
method: "POST",
body: JSON.stringify({ name: "" }),
headers: { "Content-Type": "application/json" },
});
assertEquals(res.status, 400);
});
});bash
undefinedDependency inspection
运行测试
deno info src/main.ts
deno test --allow-net --allow-env
undefinedCompile to standalone executable
内置工具
deno compile --allow-net --allow-env --allow-read src/main.ts
undefinedbash
undefinedWeb Standards
代码格式化(使用Deno默认规则)
Deno and Hono embrace web standards. Use:
- for HTTP requests to external APIs
fetch() - and
Requestobjects (native to Hono)Response - and
URLfor URL manipulationURLSearchParams - for cryptography
Web Crypto API - for large response bodies
Streams API - for multipart data handling
FormData - for request/response headers
Headers
deno fmt
Performance
代码检查
- Use via Hono for high-performance HTTP
Deno.serve() - Leverage streaming responses for large payloads
- Use connection pooling for database connections
- Compile to standalone executables for deployment
- Use Deno Deploy for edge deployment
deno lint
Run Commands
类型检查
bash
undefineddeno check src/**/*.ts
Development with hot reload
依赖分析
deno task dev
deno info src/main.ts
Production
编译为独立可执行文件
deno task start
deno compile --allow-net --allow-env --allow-read src/main.ts
undefinedFormat and check
Web标准
deno task check
Deno和Hono拥抱Web标准。建议使用:
- 调用外部API
fetch() - 和
Request对象(Hono原生支持)Response - 和
URL处理URLURLSearchParams - 进行加密操作
Web Crypto API - 处理大响应体
Streams API - 处理多部分数据
FormData - 处理请求/响应头
Headers
Direct execution
性能优化
deno run --allow-net --allow-env --allow-read src/main.ts
undefined- 通过Hono使用实现高性能HTTP服务
Deno.serve() - 大 payload 使用流式响应
- 数据库连接使用连接池
- 编译为独立可执行文件部署
- 使用Deno Deploy进行边缘部署
—
运行命令
—
bash
undefined—
开发模式(热重载)
—
deno task dev
—
生产模式
—
deno task start
—
格式化与检查
—
deno task check
—
直接运行
—
deno run --allow-net --allow-env --allow-read src/main.ts
undefined