Koa路由系统详解
1. 路由系统概述
路由是Web应用的核心概念之一,它负责将HTTP请求映射到相应的处理函数。在Koa中,路由系统不是框架核心的一部分,而是通过第三方中间件如koa-router来实现的。本章将深入探讨Koa的路由系统,包括基本用法、高级特性和最佳实践。
1.1 路由的基本概念
路由(路由)是指根据URL和HTTP方法将请求映射到处理函数的机制。在Web应用中,路由通常由以下几个部分组成:
- URL模式:用于匹配请求的URL
- HTTP方法:如GET、POST、PUT、DELETE等
- 处理函数:当请求匹配路由时执行的函数
1.2 Koa路由系统的特点
- 轻量级:Koa本身不包含路由功能,需要使用第三方中间件
- 灵活:支持命名路由、路由参数、路由前缀等高级特性
- 可组合:支持路由嵌套和组合,便于组织大型应用的路由结构
- 中间件集成:支持在路由级别使用中间件
2. koa-router中间件
2.1 安装与基本配置
koa-router是Koa最常用的路由中间件,提供了完整的路由功能。
npm install koa-router
基本使用:
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
// 定义路由
router.get('/', async ctx => {
ctx.body = 'Hello World';
});
// 应用路由中间件
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
2.2 路由注册方法
koa-router支持以下HTTP方法的路由注册:
// HTTP方法路由
router.get('/path', handler);
router.post('/path', handler);
router.put('/path', handler);
router.delete('/path', handler);
router.patch('/path', handler);
router.head('/path', handler);
router.options('/path', handler);
// 支持多个HTTP方法
router.methods(['GET', 'POST'], '/path', handler);
// 匹配所有HTTP方法
router.all('/path', handler);
2.3 路由处理函数
路由处理函数是一个接收Koa上下文对象的async函数:
router.get('/users', async (ctx) => {
// 获取请求数据
const query = ctx.query;
const params = ctx.params;
const body = ctx.request.body;
// 处理业务逻辑
const users = await getUserList(query);
// 设置响应
ctx.status = 200;
ctx.body = {
code: 200,
message: 'Success',
data: users
};
});
3. 路由参数
3.1 路径参数
路由路径参数允许在URL中捕获动态值:
// 单个参数
router.get('/users/:id', async ctx => {
const id = ctx.params.id;
ctx.body = `用户ID: ${id}`;
});
// 多个参数
router.get('/users/:userId/posts/:postId', async ctx => {
const { userId, postId } = ctx.params;
ctx.body = `用户ID: ${userId}, 文章ID: ${postId}`;
});
// 可选参数(使用?)
router.get('/users/:id?', async ctx => {
const id = ctx.params.id || 'all';
ctx.body = `用户ID: ${id}`;
});
// 正则表达式参数
router.get('/files/:file(.*)', async ctx => {
const file = ctx.params.file;
ctx.body = `文件路径: ${file}`;
});
3.2 查询参数
查询参数是URL中?后面的键值对,Koa会自动解析它们:
router.get('/search', async ctx => {
// GET /search?keyword=koa&page=1
const { keyword, page } = ctx.query;
ctx.body = { keyword, page };
});
3.3 参数验证
对于路由参数的验证,可以使用第三方库如Joi、express-validator等:
const Joi = require('joi');
router.get('/users/:id', async ctx => {
// 验证ID参数
const schema = Joi.object({
id: Joi.number().integer().min(1).required()
});
try {
// 验证参数
await schema.validateAsync({ id: ctx.params.id });
// 处理业务逻辑
ctx.body = `用户ID: ${ctx.params.id}`;
} catch (error) {
ctx.status = 400;
ctx.body = {
code: 400,
message: error.details[0].message
};
}
});
4. 路由中间件
4.1 路由级中间件
可以为特定路由或路由组应用中间件:
// 单路由中间件
router.get('/users', authMiddleware, async ctx => {
ctx.body = '用户列表';
});
// 多个中间件
router.post('/users', validateMiddleware, authMiddleware, async ctx => {
ctx.body = '创建用户成功';
});
// 路由组中间件
router.use('/admin', adminMiddleware);
router.get('/admin/dashboard', async ctx => {
ctx.body = '管理面板';
});
4.2 路由前缀
可以为一组路由设置统一的前缀:
// 创建带前缀的路由
const apiRouter = new Router({ prefix: '/api' });
// 这些路由将自动添加/api前缀
apiRouter.get('/users', async ctx => {
ctx.body = 'API用户列表';
});
apiRouter.post('/users', async ctx => {
ctx.body = '创建API用户';
});
// 应用路由
app.use(apiRouter.routes());
4.3 嵌套路由
路由可以嵌套,便于组织复杂的路由结构:
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
const userRouter = new Router();
const postRouter = new Router();
// 用户路由
userRouter.get('/', async ctx => {
ctx.body = '用户列表';
});
userRouter.get('/:id', async ctx => {
ctx.body = `用户 ${ctx.params.id}`;
});
// 文章路由
postRouter.get('/', async ctx => {
ctx.body = '文章列表';
});
postRouter.get('/:id', async ctx => {
ctx.body = `文章 ${ctx.params.id}`;
});
// 嵌套路由
router.use('/users', userRouter.routes(), userRouter.allowedMethods());
router.use('/posts', postRouter.routes(), postRouter.allowedMethods());
// 应用主路由
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
5. 高级路由特性
5.1 命名路由
可以为路由指定名称,便于生成URL:
// 定义命名路由
router.get('user-detail', '/users/:id', async ctx => {
ctx.body = `用户 ${ctx.params.id}`;
});
// 生成URL
const url = router.url('user-detail', { id: 123 }); // /users/123
// 在路由处理函数中生成URL
router.get('/links', async ctx => {
const userUrl = ctx.router.url('user-detail', { id: 123 });
ctx.body = { userUrl };
});
5.2 路由重定向
可以使用路由重定向功能将一个路由重定向到另一个路由:
// 简单重定向
router.redirect('/login', '/auth/login');
// 带状态码的重定向(默认301)
router.redirect('/old', '/new', 302);
// 在路由处理函数中重定向
router.get('/home', async ctx => {
ctx.redirect('/dashboard');
});
5.3 路由参数预处理
可以对路由参数进行预处理:
// 注册参数预处理函数
router.param('id', async (id, ctx, next) => {
// 预处理ID参数
ctx.state.user = { id: parseInt(id) };
await next();
});
// 使用预处理后的参数
router.get('/users/:id', async ctx => {
ctx.body = `用户ID: ${ctx.state.user.id}`;
});
5.4 路由优先级
路由的定义顺序会影响匹配优先级,更具体的路由应该放在前面:
// 更具体的路由放在前面
router.get('/users/new', async ctx => {
ctx.body = '创建新用户';
});
// 更通用的路由放在后面
router.get('/users/:id', async ctx => {
ctx.body = `用户 ${ctx.params.id}`;
});
6. 路由模块化
在大型应用中,将路由模块化是一种良好的实践。
6.1 路由文件组织
推荐的路由文件组织结构:
app/
├── routes/
│ ├── index.js # 路由入口文件
│ ├── users.js # 用户相关路由
│ ├── posts.js # 文章相关路由
│ └── admin.js # 管理相关路由
├── controllers/ # 控制器文件
└── app.js # 应用入口文件
6.2 路由模块化实现
用户路由 (routes/users.js):
const Router = require('koa-router');
const router = new Router({ prefix: '/users' });
// 引入控制器
const userController = require('../controllers/userController');
// 定义路由
router.get('/', userController.getAllUsers);
router.get('/:id', userController.getUserById);
router.post('/', userController.createUser);
router.put('/:id', userController.updateUser);
router.delete('/:id', userController.deleteUser);
module.exports = router;
文章路由 (routes/posts.js):
const Router = require('koa-router');
const router = new Router({ prefix: '/posts' });
// 引入控制器
const postController = require('../controllers/postController');
// 定义路由
router.get('/', postController.getAllPosts);
router.get('/:id', postController.getPostById);
router.post('/', postController.createPost);
router.put('/:id', postController.updatePost);
router.delete('/:id', postController.deletePost);
module.exports = router;
路由入口文件 (routes/index.js):
const Router = require('koa-router');
const router = new Router();
// 引入各模块路由
const userRoutes = require('./users');
const postRoutes = require('./posts');
// 挂载子路由
router.use(userRoutes.routes(), userRoutes.allowedMethods());
router.use(postRoutes.routes(), postRoutes.allowedMethods());
module.exports = router;
应用入口文件 (app.js):
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
// 引入路由
const routes = require('./routes');
const app = new Koa();
// 应用中间件
app.use(bodyParser());
// 应用路由
app.use(routes.routes());
app.use(routes.allowedMethods());
app.listen(3000);
7. 路由与控制器
在MVC架构中,路由负责请求的分发,而控制器负责具体的业务逻辑处理。
7.1 控制器模式
控制器是处理请求、执行业务逻辑并返回响应的组件。
用户控制器 (controllers/userController.js):
// 引入服务层
const userService = require('../services/userService');
const userController = {
// 获取所有用户
getAllUsers: async (ctx) => {
try {
const users = await userService.getAllUsers();
ctx.status = 200;
ctx.body = {
code: 200,
message: 'Success',
data: users
};
} catch (error) {
ctx.status = 500;
ctx.body = {
code: 500,
message: error.message
};
}
},
// 获取单个用户
getUserById: async (ctx) => {
try {
const user = await userService.getUserById(ctx.params.id);
if (!user) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'User not found'
};
return;
}
ctx.status = 200;
ctx.body = {
code: 200,
message: 'Success',
data: user
};
} catch (error) {
ctx.status = 500;
ctx.body = {
code: 500,
message: error.message
};
}
},
// 创建用户
createUser: async (ctx) => {
try {
const newUser = await userService.createUser(ctx.request.body);
ctx.status = 201;
ctx.body = {
code: 201,
message: 'User created',
data: newUser
};
} catch (error) {
ctx.status = 400;
ctx.body = {
code: 400,
message: error.message
};
}
},
// 更新用户
updateUser: async (ctx) => {
try {
const updatedUser = await userService.updateUser(ctx.params.id, ctx.request.body);
if (!updatedUser) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'User not found'
};
return;
}
ctx.status = 200;
ctx.body = {
code: 200,
message: 'User updated',
data: updatedUser
};
} catch (error) {
ctx.status = 400;
ctx.body = {
code: 400,
message: error.message
};
}
},
// 删除用户
deleteUser: async (ctx) => {
try {
const deletedUser = await userService.deleteUser(ctx.params.id);
if (!deletedUser) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'User not found'
};
return;
}
ctx.status = 200;
ctx.body = {
code: 200,
message: 'User deleted'
};
} catch (error) {
ctx.status = 500;
ctx.body = {
code: 500,
message: error.message
};
}
}
};
module.exports = userController;
7.2 服务层
服务层包含业务逻辑,与数据访问层交互:
用户服务 (services/userService.js):
// 引入数据访问层
const userModel = require('../models/userModel');
const userService = {
// 获取所有用户
getAllUsers: async () => {
return await userModel.findAll();
},
// 获取单个用户
getUserById: async (id) => {
return await userModel.findById(id);
},
// 创建用户
createUser: async (userData) => {
// 验证用户数据
if (!userData.name || !userData.email) {
throw new Error('Name and email are required');
}
// 检查邮箱是否已存在
const existingUser = await userModel.findByEmail(userData.email);
if (existingUser) {
throw new Error('Email already exists');
}
// 创建用户
return await userModel.create(userData);
},
// 更新用户
updateUser: async (id, userData) => {
// 检查用户是否存在
const existingUser = await userModel.findById(id);
if (!existingUser) {
return null;
}
// 验证更新数据
if (userData.email) {
// 检查新邮箱是否已被使用
const emailUser = await userModel.findByEmail(userData.email);
if (emailUser && emailUser.id !== id) {
throw new Error('Email already exists');
}
}
// 更新用户
return await userModel.update(id, userData);
},
// 删除用户
deleteUser: async (id) => {
// 检查用户是否存在
const existingUser = await userModel.findById(id);
if (!existingUser) {
return null;
}
// 删除用户
return await userModel.delete(id);
}
};
module.exports = userService;
8. RESTful API设计
8.1 RESTful API概念
REST (Representational State Transfer) 是一种软件架构风格,用于设计网络应用程序。RESTful API 是符合REST原则的API设计。
8.2 RESTful路由设计
RESTful API通常使用以下路由模式:
| HTTP方法 | 路由 | 描述 |
|---|---|---|
| GET | /resources | 获取资源列表 |
| GET | /resources/:id | 获取单个资源 |
| POST | /resources | 创建新资源 |
| PUT | /resources/:id | 更新资源 |
| DELETE | /resources/:id | 删除资源 |
8.3 Koa实现RESTful API
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
const router = new Router({ prefix: '/api' });
// 模拟数据
let users = [
{ id: 1, name: '张三', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', email: 'lisi@example.com' }
];
// 获取所有用户
router.get('/users', async ctx => {
ctx.body = {
code: 200,
message: 'Success',
data: users
};
});
// 获取单个用户
router.get('/users/:id', async ctx => {
const id = parseInt(ctx.params.id);
const user = users.find(u => u.id === id);
if (!user) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'User not found'
};
return;
}
ctx.body = {
code: 200,
message: 'Success',
data: user
};
});
// 创建用户
router.post('/users', async ctx => {
const { name, email } = ctx.request.body;
if (!name || !email) {
ctx.status = 400;
ctx.body = {
code: 400,
message: 'Name and email are required'
};
return;
}
// 检查邮箱是否已存在
if (users.some(u => u.email === email)) {
ctx.status = 400;
ctx.body = {
code: 400,
message: 'Email already exists'
};
return;
}
// 创建新用户
const newUser = {
id: users.length + 1,
name,
email
};
users.push(newUser);
ctx.status = 201;
ctx.body = {
code: 201,
message: 'User created',
data: newUser
};
});
// 更新用户
router.put('/users/:id', async ctx => {
const id = parseInt(ctx.params.id);
const { name, email } = ctx.request.body;
const userIndex = users.findIndex(u => u.id === id);
if (userIndex === -1) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'User not found'
};
return;
}
// 检查邮箱是否已被其他用户使用
if (email && users.some(u => u.email === email && u.id !== id)) {
ctx.status = 400;
ctx.body = {
code: 400,
message: 'Email already exists'
};
return;
}
// 更新用户
users[userIndex] = {
...users[userIndex],
...(name && { name }),
...(email && { email })
};
ctx.body = {
code: 200,
message: 'User updated',
data: users[userIndex]
};
});
// 删除用户
router.delete('/users/:id', async ctx => {
const id = parseInt(ctx.params.id);
const userIndex = users.findIndex(u => u.id === id);
if (userIndex === -1) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'User not found'
};
return;
}
// 删除用户
users.splice(userIndex, 1);
ctx.body = {
code: 200,
message: 'User deleted'
};
});
// 应用中间件
app.use(bodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
9. 路由安全
9.1 输入验证
对所有用户输入进行验证是防止安全漏洞的重要措施:
const Joi = require('joi');
// 定义验证中间件
const validate = (schema) => {
return async (ctx, next) => {
try {
await schema.validateAsync(ctx.request.body);
await next();
} catch (error) {
ctx.status = 400;
ctx.body = {
code: 400,
message: error.details[0].message
};
}
};
};
// 用户创建验证规则
const userSchema = Joi.object({
name: Joi.string().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required()
});
// 应用验证中间件
router.post('/users', validate(userSchema), async ctx => {
// 处理创建用户的逻辑
});
9.2 路径遍历防护
防止路径遍历攻击:
const path = require('path');
router.get('/files/:file*', async ctx => {
// 获取请求的文件路径
let filePath = ctx.params.file || '';
// 规范化路径
const normalizedPath = path.normalize(filePath);
// 检查是否存在路径遍历尝试
if (normalizedPath.includes('..')) {
ctx.status = 403;
ctx.body = {
code: 403,
message: 'Forbidden'
};
return;
}
// 处理文件请求
// ...
});
9.3 速率限制
使用速率限制中间件防止暴力攻击:
npm install koa-ratelimit
const ratelimit = require('koa-ratelimit');
const Redis = require('ioredis');
const redis = new Redis();
// 速率限制配置
const limiter = ratelimit({
db: redis,
duration: 60000, // 60秒
max: 100, // 最多100个请求
id: (ctx) => ctx.ip, // 使用IP作为标识符
errorMessage: 'Too many requests',
});
// 应用速率限制中间件
router.use('/api', limiter);
10. 路由测试
10.1 单元测试
使用Jest等测试框架测试路由处理函数:
npm install --save-dev jest supertest
测试文件 (test/routes.test.js):
const request = require('supertest');
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
// 创建测试应用
function createTestApp() {
const app = new Koa();
const router = new Router();
// 定义测试路由
router.get('/users', async ctx => {
ctx.body = {
code: 200,
data: [{ id: 1, name: 'Test User' }]
};
});
router.post('/users', async ctx => {
const { name } = ctx.request.body;
ctx.status = 201;
ctx.body = {
code: 201,
data: { id: 1, name }
};
});
// 应用中间件
app.use(bodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
return app.callback();
}
// 测试路由
describe('Routes', () => {
const app = createTestApp();
test('GET /users should return users', async () => {
const response = await request(app).get('/users');
expect(response.status).toBe(200);
expect(response.body.code).toBe(200);
expect(response.body.data).toHaveLength(1);
});
test('POST /users should create user', async () => {
const response = await request(app)
.post('/users')
.send({ name: 'New User' });
expect(response.status).toBe(201);
expect(response.body.code).toBe(201);
expect(response.body.data.name).toBe('New User');
});
});
10.2 集成测试
测试路由与控制器、服务层的集成:
const request = require('supertest');
const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-bodyparser');
// 模拟服务层
jest.mock('../services/userService', () => ({
getAllUsers: jest.fn().mockResolvedValue([{ id: 1, name: 'Mock User' }]),
createUser: jest.fn().mockImplementation(data =>
Promise.resolve({ id: 1, ...data })
)
}));
// 创建应用
function createApp() {
const app = new Koa();
const router = new Router();
// 引入控制器
const userController = require('../controllers/userController');
// 定义路由
router.get('/users', userController.getAllUsers);
router.post('/users', userController.createUser);
// 应用中间件
app.use(bodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
return app.callback();
}
// 集成测试
describe('Integration Tests', () => {
const app = createApp();
test('GET /users should return users from service', async () => {
const response = await request(app).get('/users');
expect(response.status).toBe(200);
expect(response.body.data).toHaveLength(1);
});
test('POST /users should create user through service', async () => {
const response = await request(app)
.post('/users')
.send({ name: 'Test', email: 'test@example.com' });
expect(response.status).toBe(201);
});
});
11. 实战案例:构建博客API
11.1 项目概述
在这个实战案例中,我们将构建一个完整的博客API,包含用户、文章、评论等功能模块。
11.2 技术栈
- Koa 2.x
- koa-router
- koa-bodyparser
- koa-session
- Joi (数据验证)
- 内存存储(实际项目中可替换为数据库)
11.3 项目结构
blog-api/
├── app.js
├── package.json
├── config/
│ └── index.js
├── middlewares/
│ ├── auth.js
│ ├── errorHandler.js
│ └── validator.js
├── controllers/
│ ├── userController.js
│ ├── postController.js
│ └── commentController.js
├── services/
│ ├── userService.js
│ ├── postService.js
│ └── commentService.js
├── models/
│ ├── userModel.js
│ ├── postModel.js
│ └── commentModel.js
└── routes/
├── index.js
├── userRoutes.js
├── postRoutes.js
└── commentRoutes.js
11.4 实现核心功能
1. 错误处理中间件 (middlewares/errorHandler.js)
module.exports = async (ctx, next) => {
try {
await next();
// 处理404错误
if (ctx.status === 404 && !ctx.body) {
ctx.status = 404;
ctx.body = {
code: 404,
message: 'Not Found'
};
}
} catch (err) {
console.error('Error:', err);
ctx.status = err.status || 500;
ctx.body = {
code: err.code || ctx.status,
message: err.message || 'Internal Server Error'
};
ctx.app.emit('error', err, ctx);
}
};
2. 身份验证中间件 (middlewares/auth.js)
module.exports = async (ctx, next) => {
// 检查是否已登录
if (!ctx.session.user) {
ctx.status = 401;
ctx.body = {
code: 401,
message: 'Unauthorized'
};
return;
}
// 将用户信息保存到上下文
ctx.user = ctx.session.user;
await next();
};
3. 用户路由 (routes/userRoutes.js)
const Router = require('koa-router');
const router = new Router({ prefix: '/api/users' });
const userController = require('../controllers/userController');
const auth = require('../middlewares/auth');
// 公共路由
router.post('/register', userController.register);
router.post('/login', userController.login);
router.post('/logout', userController.logout);
// 需要身份验证的路由
router.get('/profile', auth, userController.getProfile);
router.put('/profile', auth, userController.updateProfile);
module.exports = router;
4. 文章路由 (routes/postRoutes.js)
const Router = require('koa-router');
const router = new Router({ prefix: '/api/posts' });
const postController = require('../controllers/postController');
const auth = require('../middlewares/auth');
// 公共路由
router.get('/', postController.getAllPosts);
router.get('/:id', postController.getPostById);
// 需要身份验证的路由
router.post('/', auth, postController.createPost);
router.put('/:id', auth, postController.updatePost);
router.delete('/:id', auth, postController.deletePost);
module.exports = router;
5. 评论路由 (routes/commentRoutes.js)
const Router = require('koa-router');
const router = new Router({ prefix: '/api/comments' });
const commentController = require('../controllers/commentController');
const auth = require('../middlewares/auth');
// 公共路由
router.get('/post/:postId', commentController.getCommentsByPostId);
// 需要身份验证的路由
router.post('/', auth, commentController.createComment);
router.put('/:id', auth, commentController.updateComment);
router.delete('/:id', auth, commentController.deleteComment);
module.exports = router;
6. 路由整合 (routes/index.js)
const Router = require('koa-router');
const router = new Router();
// 引入各模块路由
const userRoutes = require('./userRoutes');
const postRoutes = require('./postRoutes');
const commentRoutes = require('./commentRoutes');
// 挂载路由
router.use(userRoutes.routes(), userRoutes.allowedMethods());
router.use(postRoutes.routes(), postRoutes.allowedMethods());
router.use(commentRoutes.routes(), commentRoutes.allowedMethods());
module.exports = router;
7. 应用入口 (app.js)
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const session = require('koa-session');
// 中间件
const errorHandler = require('./middlewares/errorHandler');
// 路由
const routes = require('./routes');
// 创建应用
const app = new Koa();
const PORT = 3000;
// 配置
app.keys = ['blog-api-secret-key'];
// 应用中间件
app.use(errorHandler);
app.use(session({
key: 'blog:sess',
maxAge: 86400000,
httpOnly: true,
signed: true
}, app));
app.use(bodyParser());
// 应用路由
app.use(routes.routes());
app.use(routes.allowedMethods());
// 启动服务器
app.listen(PORT, () => {
console.log(`Blog API running on http://localhost:${PORT}`);
});
11.5 测试博客API
使用curl或Postman测试以下API端点:
-
用户相关:
- POST /api/users/register - 注册用户
- POST /api/users/login - 用户登录
- POST /api/users/logout - 用户登出
- GET /api/users/profile - 获取用户信息
- PUT /api/users/profile - 更新用户信息
-
文章相关:
- GET /api/posts - 获取所有文章
- GET /api/posts/:id - 获取单篇文章
- POST /api/posts - 创建文章(需要登录)
- PUT /api/posts/:id - 更新文章(需要登录)
- DELETE /api/posts/:id - 删除文章(需要登录)
-
评论相关:
- GET /api/comments/post/:postId - 获取文章评论
- POST /api/comments - 创建评论(需要登录)
- PUT /api/comments/:id - 更新评论(需要登录)
- DELETE /api/comments/:id - 删除评论(需要登录)
12. 总结与进阶建议
通过本章节的学习,你应该已经掌握了Koa路由系统的核心概念、基本用法和高级特性。路由是Web应用的重要组成部分,合理的路由设计和组织对于构建可维护、可扩展的应用至关重要。
进阶学习建议
- 学习更多高级路由技术,如路由缓存、路由预热等
- 探索其他路由中间件,如koa-route、koa-compose等
- 深入理解RESTful API设计原则和最佳实践
- 学习API文档生成工具,如Swagger、API Blueprint等
- 了解API版本控制策略
在下一章节,我们将深入学习Koa的错误处理机制,了解如何构建健壮的错误处理系统。