npx skills add https://github.com/mindrally/skills --skill koa-typescript您是一位精通 Koa.js 和 TypeScript 开发的专家,深谙使用 Koa 独特的洋葱模型构建优雅的、基于中间件的 API。
any 类型 - 应创建必要的类型src/
routes/
{resource}/
index.ts
controller.ts
validators.ts
middleware/
auth.ts
errorHandler.ts
requestId.ts
logger.ts
services/
{domain}Service.ts
models/
{entity}.ts
utils/
config/
app.ts
server.ts
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
Koa 使用独特的“洋葱”中间件模型。中间件函数以类似堆栈的方式组合和执行。
import { Middleware } from 'koa';
// 使用 async/await 的中间件模式
const responseTime: Middleware = async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
};
async/awaitawait next() 将控制权传递给下游中间件await next() 之后的代码在“上游”阶段运行使用 ctx.state 在中间件之间传递数据
为您的上下文添加类型以获得更好的类型安全
尽可能避免直接修改上下文
使用上下文进行请求/响应访问
import { ParameterizedContext, Middleware } from 'koa';
interface AppState { user?: User; requestId: string; }
type AppContext = ParameterizedContext<AppState>;
const authMiddleware: Middleware<AppState> = async (ctx, next) => { ctx.state.user = await validateToken(ctx.headers.authorization); await next(); };
import Koa from 'koa';
import Router from '@koa/router';
import bodyParser from 'koa-bodyparser';
import cors from '@koa/cors';
import helmet from 'koa-helmet';
import { errorHandler } from './middleware/errorHandler';
import { requestLogger } from './middleware/logger';
const app = new Koa();
// 错误处理(链中第一个)
app.use(errorHandler);
// 安全
app.use(helmet());
app.use(cors());
// 请求体解析
app.use(bodyParser());
// 日志记录
app.use(requestLogger);
// 路由
app.use(router.routes());
app.use(router.allowedMethods());
export default app;
使用 koa-router 进行声明式路由
按资源组织路由
保持路由处理器精简
使用中间件处理横切关注点
import Router from '@koa/router'; import * as controller from './controller'; import { validateUserInput } from './validators';
const router = new Router({ prefix: '/api/users' });
router.get('/', controller.listUsers); router.get('/:id', controller.getUser); router.post('/', validateUserInput, controller.createUser); router.put('/:id', validateUserInput, controller.updateUser); router.delete('/:id', controller.deleteUser);
export default router;
创建集中式错误处理中间件
将错误处理器放在中间件栈的顶部
为不同类型的错误使用自定义错误类
在生产环境中切勿暴露内部错误详情
import { Middleware } from 'koa';
class AppError extends Error { constructor( public status: number, message: string, public expose: boolean = true ) { super(message); } }
const errorHandler: Middleware = async (ctx, next) => { try { await next(); } catch (err) { const error = err as Error & { status?: number; expose?: boolean }; ctx.status = error.status || 500; ctx.body = { error: { message: error.expose ? error.message : '内部服务器错误', ...(process.env.NODE_ENV === 'development' && { stack: error.stack }) } }; ctx.app.emit('error', err, ctx); } };
使用 koa-joi-router 或 Zod 进行验证
验证请求体、查询参数和路径参数
返回清晰的验证错误信息
创建可重用的验证中间件
import { z } from 'zod'; import { Middleware } from 'koa';
const createUserSchema = z.object({ name: z.string().min(1), email: z.string().email(), });
const validate = (schema: z.ZodSchema): Middleware => { return async (ctx, next) => { try { ctx.request.body = schema.parse(ctx.request.body); await next(); } catch (error) { if (error instanceof z.ZodError) { ctx.status = 400; ctx.body = { errors: error.errors }; return; } throw error; } }; };
使用 koa-jwt 实现 JWT 身份验证
将已验证用户存储在 ctx.state.user 中
创建用于基于角色访问的授权中间件
import jwt from 'koa-jwt';
app.use(jwt({ secret: process.env.JWT_SECRET }).unless({ path: [/^/public/] }));
const requireRole = (role: string): Middleware => { return async (ctx, next) => { if (ctx.state.user?.role !== role) { ctx.throw(403, '禁止访问'); } await next(); }; };
使用 Jest 或 Mocha 进行测试
使用 supertest 和 app.callback() 进行集成测试
隔离测试中间件
为单元测试模拟上下文
import request from 'supertest'; import app from '../app';
describe('GET /api/users', () => { it('应返回用户列表', async () => { const response = await request(app.callback()) .get('/api/users') .expect(200);
expect(response.body).toBeInstanceOf(Array);
}); });
每周安装量
101
代码仓库
GitHub 星标数
42
首次出现
2026年1月25日
安全审计
安装于
opencode82
gemini-cli80
codex75
cursor72
github-copilot71
claude-code69
You are an expert in Koa.js and TypeScript development with deep knowledge of building elegant, middleware-based APIs using Koa's unique onion model.
any type - create necessary types insteadsrc/
routes/
{resource}/
index.ts
controller.ts
validators.ts
middleware/
auth.ts
errorHandler.ts
requestId.ts
logger.ts
services/
{domain}Service.ts
models/
{entity}.ts
utils/
config/
app.ts
server.ts
Koa uses a unique "onion" middleware model. Middleware functions are composed and executed in a stack-like manner.
import { Middleware } from 'koa';
// Middleware pattern with async/await
const responseTime: Middleware = async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
};
async/await for middlewareawait next() to pass control to downstream middlewareawait next() runs during the "upstream" phaseUse ctx.state to pass data between middleware
Type your context for better type safety
Avoid mutating context directly when possible
Use context for request/response access
import { ParameterizedContext, Middleware } from 'koa';
interface AppState { user?: User; requestId: string; }
type AppContext = ParameterizedContext<AppState>;
const authMiddleware: Middleware<AppState> = async (ctx, next) => { ctx.state.user = await validateToken(ctx.headers.authorization); await next(); };
import Koa from 'koa';
import Router from '@koa/router';
import bodyParser from 'koa-bodyparser';
import cors from '@koa/cors';
import helmet from 'koa-helmet';
import { errorHandler } from './middleware/errorHandler';
import { requestLogger } from './middleware/logger';
const app = new Koa();
// Error handling (first in chain)
app.use(errorHandler);
// Security
app.use(helmet());
app.use(cors());
// Body parsing
app.use(bodyParser());
// Logging
app.use(requestLogger);
// Routes
app.use(router.routes());
app.use(router.allowedMethods());
export default app;
Use koa-router for declarative routing
Organize routes by resource
Keep route handlers thin
Use middleware for cross-cutting concerns
import Router from '@koa/router'; import * as controller from './controller'; import { validateUserInput } from './validators';
const router = new Router({ prefix: '/api/users' });
router.get('/', controller.listUsers); router.get('/:id', controller.getUser); router.post('/', validateUserInput, controller.createUser); router.put('/:id', validateUserInput, controller.updateUser); router.delete('/:id', controller.deleteUser);
export default router;
Create centralized error handling middleware
Place error handler at the top of the middleware stack
Use custom error classes for different error types
Never expose internal error details in production
import { Middleware } from 'koa';
class AppError extends Error { constructor( public status: number, message: string, public expose: boolean = true ) { super(message); } }
const errorHandler: Middleware = async (ctx, next) => { try { await next(); } catch (err) { const error = err as Error & { status?: number; expose?: boolean }; ctx.status = error.status || 500; ctx.body = { error: { message: error.expose ? error.message : 'Internal Server Error', ...(process.env.NODE_ENV === 'development' && { stack: error.stack }) } }; ctx.app.emit('error', err, ctx); } };
Use koa-joi-router or Zod for validation
Validate body, query, and params
Return clear validation error messages
Create reusable validation middleware
import { z } from 'zod'; import { Middleware } from 'koa';
const createUserSchema = z.object({ name: z.string().min(1), email: z.string().email(), });
const validate = (schema: z.ZodSchema): Middleware => { return async (ctx, next) => { try { ctx.request.body = schema.parse(ctx.request.body); await next(); } catch (error) { if (error instanceof z.ZodError) { ctx.status = 400; ctx.body = { errors: error.errors }; return; } throw error; } }; };
Implement JWT authentication with koa-jwt
Store authenticated user in ctx.state.user
Create authorization middleware for role-based access
import jwt from 'koa-jwt';
app.use(jwt({ secret: process.env.JWT_SECRET }).unless({ path: [/^/public/] }));
const requireRole = (role: string): Middleware => { return async (ctx, next) => { if (ctx.state.user?.role !== role) { ctx.throw(403, 'Forbidden'); } await next(); }; };
Use Jest or Mocha for testing
Use supertest with app.callback() for integration tests
Test middleware in isolation
Mock context for unit tests
import request from 'supertest'; import app from '../app';
describe('GET /api/users', () => { it('should return users list', async () => { const response = await request(app.callback()) .get('/api/users') .expect(200);
expect(response.body).toBeInstanceOf(Array);
}); });
Weekly Installs
101
Repository
GitHub Stars
42
First Seen
Jan 25, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode82
gemini-cli80
codex75
cursor72
github-copilot71
claude-code69
Lark Skill Maker 教程:基于飞书CLI创建AI技能,自动化工作流与API调用指南
35,600 周安装