添加路由(处理不同的URL请求)
路由:根据不同的URL,调用对应的处理函数。
每一个接口服务,最核心的功能是:根据不同的URL请求,返回不同的数据。也就是调用不同的接口返回不同的数据。
在 Node.js 中使用 Koa 框架添加路由可以通过以下几种方式实现:
第1种:使用原生的 app.use
和条件判断
typescript
// 导入koa, koa是一个类
const Koa = require('koa')
const { APP_PORT } = require('./config/config.env')
// 创建koa实例对象:app
const app = new Koa()
// 使用 app.use() 方法添加中间件,且只能写一个中间件
app.use((ctx, next) => {
// 中间件逻辑
if (ctx.url === '/home') {
ctx.body = 'This is the home page';
} else if (ctx.url === '/about') {
ctx.body = 'This is the about page';
} else {
ctx.body = 'Page not found';
}
});
// 指定端口号并启动服务器
app.listen(APP_PORT, () => {
console.log(`server is running on http://localhost:${APP_PORT}`)
})
第2种:使用第三方路由模块,如 koa-router
(常用)
安装koa-router
:
shell
npm install koa-router -D
API 介绍
typescript
const Router = require('koa-router');
const router = new Router();
new Router([options])
:创建一个新的路由实例。options
可以是一个包含配置选项的对象,例如设置路由前缀prefix
等。router.get(path, [middleware,...], callback)
:定义处理 GET 请求的路由。router.post(path, [middleware,...], callback)
:定义处理 POST 请求的路由。router.put(path, [middleware,...], callback)
:定义处理 PUT 请求的路由。router.delete(path, [middleware,...], callback)
:定义处理 DELETE 请求的路由。router.patch(path, [middleware,...], callback)
:定义处理 PATCH 请求的路由。
typescript
router.get('/users', async (ctx, next) => {
ctx.body = 'Get all users';
});
router.all(path, [middleware,...], callback)
:定义处理所有 HTTP 方法的路由。
typescript
router.all('/admin', async (ctx, next) => {
if (ctx.request.method === 'GET') {
ctx.body = 'Admin page';
} else {
ctx.body = 'Not allowed';
}
});
- 在路径中使用冒号
:
来定义路由参数。可以通过ctx.params
获取参数值。
typescript
// 带参数的路由
router.get('/users/:id', async (ctx, next) => {
const userId = ctx.params.id;
ctx.body = `User with id ${userId}`;
});
- 命名路由
router.url(name, [params], [query])
:根据路由名称生成 URL。需要先给路由命名才能使用这个方法。
typescript
router.get('/login', async (ctx, next) => {
ctx.body = 'Login page';
}).name('login');
const loginUrl = router.url('login');
console.log(loginUrl);
router.allowedMethods()
:这个方法应该在所有路由定义之后添加,用于处理不支持的 HTTP 方法和发送适当的响应头。
typescript
// app 是 Koa 实例
app.use(router.routes());
app.use(router.allowedMethods());
使用示例
创建router/userRouter.js
:
typescript
// 引入路由,Router是一个类
const Router = require('koa-router');
// 创建一个路由实例 userRouter,并设置了一个前缀为 /user。
// 这意味着所有定义在这个路由实例上的路径都会自动加上这个前缀。
const userRouter = new Router({prefix: '/user'});
// 创建路由组来组织相关的路由
userRouter.get('/list', async (ctx, next) => {
// 因为有前缀,实际访问的路径是 /userlist
// 处理 GET 请求
ctx.body = 'The URL for this page is /user/list';
});
module.exports = userRouter
在 main.js
中引入并使用路由userRouter
:
typescript
const Koa = require('koa');
const { APP_PORT } = require('./config/config.env');
const userRouter = require('./router/userRoute')
// 创建koa实例对象:app
const app = new Koa();
// 注册中间件,注意:app.use 必须接收函数作为中间件
app.use(userRouter.routes())
app.use((ctx, next) => {
// 中间件逻辑
ctx.body = 'hello Koa!';
});
app.listen(APP_PORT, () => {
console.log(`server is running on http://localhost:${APP_PORT}`);
});
现在,项目目录结构如下:
项目结构优化
把http服务与app业务拆分
- 把业务代码从入口文件
main.js
中拆分出来,放到src/app/index.js
中:
javascript
const Koa = require('koa');
const userRouter = require('../router/userRoute')
// 创建koa实例对象:app
const app = new Koa();
// 注册中间件,注意:app.use 必须接收函数作为中间件
app.use(userRouter.routes())
module.exports = app
- 改写
main.js
:
javascript
// 读取配置文件
const { APP_PORT } = require('./config/config.env');
// 加载 app 模块
const app = require('./app/index')
// app 模块启动 http server
app.listen(APP_PORT, () => {
console.log(`server is running on http://localhost:${APP_PORT}`);
});
将路由和控制器拆分
路由:解析URL,分发给控制器对应的方法
控制器:处理不同的业务
示例
创建controller/userController.js
:
typescript
class userController {
async register(ctx, next) {
ctx.body = '用户注册成功'
}
async login(ctx, next) {
ctx.body = '用户登录成功'
}
}
// 导出userController的实例(new userController()是一个对象)
module.exports = new userController()
改写router/userRoute.js
:
typescript
// 引入路由,Router是一个类
const Router = require('koa-router');
// 通过解构的方式引入控制器方法
const { register, login } = require('../controller/userController')
const userRoute = new Router({prefix: '/user'});
// 注册接口
userRoute.post('/register', register);
// 登录
userRoute.post('/login', login);
module.exports = userRoute
浏览器默认发送的请求都是get
请求,如果要发送post
请求,可以使用postman
。
使用 postman
测试接口:
现在,项目目录结构如下: