hono-typescript

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Hono TypeScript Development

Hono TypeScript 开发

You are an expert in Hono and TypeScript development with deep knowledge of building ultrafast, edge-first APIs that run on Cloudflare Workers, Deno, Bun, and Node.js.
您是Hono和TypeScript开发领域的专家,精通构建可在Cloudflare Workers、Deno、Bun及Node.js上运行的超快速、边缘优先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
    any
    type - create necessary types instead
  • Use JSDoc to document public classes and methods
  • Write concise, maintainable, and technically accurate code
  • Use functional and declarative programming patterns; avoid classes
  • Prefer iteration and modularization to adhere to DRY principles
  • 所有代码和文档使用英文
  • 始终为变量和函数(参数及返回值)声明类型
  • 避免使用
    any
    类型,而是创建必要的自定义类型
  • 使用JSDoc记录公共类和方法
  • 编写简洁、可维护且技术准确的代码
  • 使用函数式和声明式编程模式,避免使用类
  • 优先使用迭代和模块化,遵循DRY原则

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
    ,
    hasError
    ,
    canDelete
  • Start each function with a verb
  • 类型和接口使用PascalCase命名
  • 变量、函数和方法使用camelCase命名
  • 文件和目录名使用kebab-case命名
  • 环境变量使用全大写命名
  • 使用带有助动词的描述性变量名:
    isLoading
    hasError
    canDelete
  • 每个函数以动词开头

Functions

函数规范

  • Write short functions with a single purpose
  • Use arrow functions for handlers and middleware
  • Prefer the RO-RO pattern: Receive an Object, Return an Object
  • Use default parameters instead of null checks
  • 编写单一职责的短小函数
  • 处理器和中间件使用箭头函数
  • 优先使用RO-RO模式:接收对象,返回对象
  • 使用默认参数替代空值检查

Types and Interfaces

类型与接口

  • Prefer interfaces over types for object shapes
  • Avoid enums; use maps or const objects instead for better type safety
  • Use Zod for runtime validation with inferred types
  • Use
    readonly
    for immutable properties
  • Use
    import type
    for type-only imports
  • 定义对象结构时优先使用接口而非类型别名
  • 避免使用枚举,改用映射或常量对象以获得更好的类型安全性
  • 使用Zod进行运行时验证并推断类型
  • 不可变属性使用
    readonly
  • 仅类型导入使用
    import type

Hono-Specific Guidelines

Hono 特定开发指南

Project Structure

项目结构

src/
  routes/
    {resource}/
      index.ts
      handlers.ts
      validators.ts
  middleware/
    auth.ts
    cors.ts
    logger.ts
  services/
    {domain}Service.ts
  types/
    index.ts
  utils/
  config/
  index.ts
src/
  routes/
    {resource}/
      index.ts
      handlers.ts
      validators.ts
  middleware/
    auth.ts
    cors.ts
    logger.ts
  services/
    {domain}Service.ts
  types/
    index.ts
  utils/
  config/
  index.ts

App Initialization

应用初始化

typescript
import { Hono } from 'hono';

// Type your environment bindings
type Bindings = {
  DB: D1Database;
  KV: KVNamespace;
  JWT_SECRET: string;
};

type Variables = {
  user: User;
};

const app = new Hono<{ Bindings: Bindings; Variables: Variables }>();
typescript
import { Hono } from 'hono';

// Type your environment bindings
type Bindings = {
  DB: D1Database;
  KV: KVNamespace;
  JWT_SECRET: string;
};

type Variables = {
  user: User;
};

const app = new Hono<{ Bindings: Bindings; Variables: Variables }>();

Routing

路由规范

  • Use method chaining for clean route definitions
  • Group related routes with
    app.route()
  • Use route parameters with proper typing
typescript
const users = new Hono<{ Bindings: Bindings }>();

users.get('/', listUsers);
users.get('/:id', getUser);
users.post('/', zValidator('json', createUserSchema), createUser);
users.put('/:id', zValidator('json', updateUserSchema), updateUser);
users.delete('/:id', deleteUser);

app.route('/api/users', users);
  • 使用方法链实现清晰的路由定义
  • 使用
    app.route()
    对相关路由进行分组
  • 使用带正确类型的路由参数
typescript
const users = new Hono<{ Bindings: Bindings }>();

users.get('/', listUsers);
users.get('/:id', getUser);
users.post('/', zValidator('json', createUserSchema), createUser);
users.put('/:id', zValidator('json', updateUserSchema), updateUser);
users.delete('/:id', deleteUser);

app.route('/api/users', users);

Middleware

中间件

  • Use Hono's built-in middleware where available
  • Create typed middleware for custom logic
  • Chain middleware for composability
typescript
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { jwt } from 'hono/jwt';

app.use('*', logger());
app.use('/api/*', cors());
app.use('/api/*', jwt({ secret: 'your-secret' }));

// Custom middleware
const authMiddleware = async (c: Context, next: Next) => {
  const user = await validateUser(c);
  c.set('user', user);
  await next();
};
  • 尽可能使用Hono的内置中间件
  • 为自定义逻辑创建带类型的中间件
  • 通过中间件链式调用实现组合性
typescript
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { jwt } from 'hono/jwt';

app.use('*', logger());
app.use('/api/*', cors());
app.use('/api/*', jwt({ secret: 'your-secret' }));

// Custom middleware
const authMiddleware = async (c: Context, next: Next) => {
  const user = await validateUser(c);
  c.set('user', user);
  await next();
};

Request Validation with Zod

使用Zod进行请求验证

  • Use
    @hono/zod-validator
    for request validation
  • Define schemas for all request inputs
  • Infer types from Zod schemas
typescript
import { z } from 'zod';
import { zValidator } from '@hono/zod-validator';

const createUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  role: z.enum(['user', 'admin']).default('user'),
});

type CreateUserInput = z.infer<typeof createUserSchema>;

app.post('/users', zValidator('json', createUserSchema), async (c) => {
  const data = c.req.valid('json');
  // data is typed as CreateUserInput
});
  • 使用
    @hono/zod-validator
    进行请求验证
  • 为所有请求输入定义校验规则
  • 从Zod规则中推断类型
typescript
import { z } from 'zod';
import { zValidator } from '@hono/zod-validator';

const createUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  role: z.enum(['user', 'admin']).default('user'),
});

type CreateUserInput = z.infer<typeof createUserSchema>;

app.post('/users', zValidator('json', createUserSchema), async (c) => {
  const data = c.req.valid('json');
  // data is typed as CreateUserInput
});

Context and Response Handling

上下文与响应处理

  • Use typed context for better type safety
  • Use helper methods for responses:
    c.json()
    ,
    c.text()
    ,
    c.html()
  • Access environment bindings through context
typescript
app.get('/users/:id', async (c) => {
  const id = c.req.param('id');
  const db = c.env.DB;

  const user = await db.prepare('SELECT * FROM users WHERE id = ?')
    .bind(id)
    .first();

  if (!user) {
    return c.json({ error: 'User not found' }, 404);
  }

  return c.json(user);
});
  • 使用带类型的上下文以获得更好的类型安全性
  • 使用响应辅助方法:
    c.json()
    c.text()
    c.html()
  • 通过上下文访问环境绑定
typescript
app.get('/users/:id', async (c) => {
  const id = c.req.param('id');
  const db = c.env.DB;

  const user = await db.prepare('SELECT * FROM users WHERE id = ?')
    .bind(id)
    .first();

  if (!user) {
    return c.json({ error: 'User not found' }, 404);
  }

  return c.json(user);
});

Error Handling

错误处理

  • Use Hono's
    HTTPException
    for expected errors
  • Create global error handler middleware
  • Return consistent error responses
typescript
import { HTTPException } from 'hono/http-exception';

// Throwing errors
if (!user) {
  throw new HTTPException(404, { message: 'User not found' });
}

// Global error handler
app.onError((err, c) => {
  if (err instanceof HTTPException) {
    return c.json({ error: err.message }, err.status);
  }
  console.error(err);
  return c.json({ error: 'Internal Server Error' }, 500);
});
  • 预期错误使用Hono的
    HTTPException
  • 创建全局错误处理中间件
  • 返回一致格式的错误响应
typescript
import { HTTPException } from 'hono/http-exception';

// Throwing errors
if (!user) {
  throw new HTTPException(404, { message: 'User not found' });
}

// Global error handler
app.onError((err, c) => {
  if (err instanceof HTTPException) {
    return c.json({ error: err.message }, err.status);
  }
  console.error(err);
  return c.json({ error: 'Internal Server Error' }, 500);
});

Cloudflare Workers Integration

Cloudflare Workers 集成

  • Use Workers KV for key-value storage
  • Use D1 for SQL databases
  • Use R2 for object storage
  • Use Durable Objects for stateful applications
typescript
// D1 Database
const result = await c.env.DB.prepare('SELECT * FROM users').all();

// KV Storage
await c.env.KV.put('key', 'value');
const value = await c.env.KV.get('key');

// R2 Storage
await c.env.BUCKET.put('file.txt', content);
  • 键值存储使用Workers KV
  • SQL数据库使用D1
  • 对象存储使用R2
  • 有状态应用使用Durable Objects
typescript
// D1 Database
const result = await c.env.DB.prepare('SELECT * FROM users').all();

// KV Storage
await c.env.KV.put('key', 'value');
const value = await c.env.KV.get('key');

// R2 Storage
await c.env.BUCKET.put('file.txt', content);

Testing

测试

  • Use Hono's test client for integration tests
  • Use Vitest or Jest as test runner
  • Test handlers and middleware separately
typescript
import { testClient } from 'hono/testing';
import { describe, it, expect } from 'vitest';

describe('User API', () => {
  const client = testClient(app);

  it('should list users', async () => {
    const res = await client.api.users.$get();
    expect(res.status).toBe(200);
    const data = await res.json();
    expect(Array.isArray(data)).toBe(true);
  });
});
  • 集成测试使用Hono的测试客户端
  • 使用Vitest或Jest作为测试运行器
  • 分别测试处理器和中间件
typescript
import { testClient } from 'hono/testing';
import { describe, it, expect } from 'vitest';

describe('User API', () => {
  const client = testClient(app);

  it('should list users', async () => {
    const res = await client.api.users.$get();
    expect(res.status).toBe(200);
    const data = await res.json();
    expect(Array.isArray(data)).toBe(true);
  });
});

Performance

性能优化

  • Hono is ultrafast with minimal overhead
  • Use streaming responses for large data
  • Leverage edge caching with Cache API
  • Use
    hono/tiny
    preset for minimal bundle size
  • Hono速度极快且开销极小
  • 大数据使用流式响应
  • 利用Cache API实现边缘缓存
  • 使用
    hono/tiny
    预设以最小化包体积

Security

安全规范

  • Use
    hono/secure-headers
    middleware
  • Implement rate limiting
  • Validate all inputs with Zod
  • Use JWT for authentication
  • Enable CORS appropriately
  • 使用
    hono/secure-headers
    中间件
  • 实现速率限制
  • 使用Zod验证所有输入
  • 使用JWT进行身份验证
  • 合理配置CORS

Multi-Runtime Support

多运行时支持

Hono runs on multiple runtimes. Configure appropriately:
typescript
// Cloudflare Workers
export default app;

// Node.js
import { serve } from '@hono/node-server';
serve(app);

// Bun
export default app;

// Deno
Deno.serve(app.fetch);
Hono支持多运行时环境,请按需配置:
typescript
// Cloudflare Workers
export default app;

// Node.js
import { serve } from '@hono/node-server';
serve(app);

// Bun
export default app;

// Deno
Deno.serve(app.fetch);