定义路由
// app/router.js
module.exports = app => {
const { router, controller, io } = app;
router.get('/user/:id', controller.user.info);
};
请求方式
- router.head - HEAD
- router.options - OPTIONS
- router.get - GET
- router.put - PUT
- router.post - POST
- router.patch - PATCH
- router.delete - DELETE
- router.del - 由于 delete 是一个保留字,所以提供了一个 delete 方法的别名。
- router.redirect - 可以对 URL 进行重定向处理,比如我们最经常使用的可以把用户访问的根目录路由到某个主页。
RESTful 风格的 URL 定义
// app/router.js
module.exports = app => {
const { router, controller } = app;
router.resources('posts', '/api/posts', controller.posts);
router.resources('users', '/api/v1/users', controller.v1.users); // app/controller/v1/users.js
};
Method | Path | Route Name | Controller.Action |
---|---|---|---|
GET | /posts | posts | app.controllers.posts.index |
GET | /posts/new | new_post | app.controllers.posts.new |
GET | /posts/:id | post | app.controllers.posts.show |
GET | /posts/:id/edit | edit_post | app.controllers.posts.edit |
POST | /posts | posts | app.controllers.posts.create |
PUT | /posts/:id | post | app.controllers.posts.update |
DELETE | /posts/:id | post | app.controllers.posts.destroy |
// app/controller/posts.js
exports.index = async () => {};
exports.new = async () => {};
exports.create = async () => {};
exports.show = async () => {};
exports.edit = async () => {};
exports.update = async () => {};
exports.destroy = async () => {};
参数规则 示例
router.verb('path-match', app.controller.action);
router.verb('router-name', 'path-match', app.controller.action);
router.verb('path-match', middleware1, ..., middlewareN, app.controller.action);
router.verb('router-name', 'path-match', middleware1, ..., middlewareN, app.controller.action);
- verb - 用户触发动作,支持 get,post 等所有 HTTP 方法,后面会通过示例详细说明。
- router.head - HEAD
- router.options - OPTIONS
- router.get - GET
- router.put - PUT
- router.post - POST
- router.patch - PATCH
- router.delete - DELETE
- router.del - 由于 delete 是一个保留字,所以提供了一个 delete 方法的别名。
- router.redirect - 可以对 URL 进行重定向处理,比如我们最经常使用的可以把用户访问的根目录路由到某个主页。
- router-name 给路由设定一个别名,可以通过 Helper 提供的辅助函数
pathFor
和urlFor
来生成 URL。(可选) - path-match - 路由 URL 路径。
- middleware1 - 在 Router 里面可以配置多个 Middleware。(可选)
- controller - 指定路由映射到的具体的 controller 上,controller 可以有两种写法:
app.controller.user.fetch
- 直接指定一个具体的 controller'user.fetch'
- 可以简写为字符串形式
示例
// app/router.js
module.exports = app => {
const { router, controller } = app;
router.get('/home', controller.home);
router.get('/user/:id', controller.user.page);
router.post('/admin', isAdmin, controller.admin);
router.post('/user', isLoginUser, hasAdminPermission, controller.user.create);
router.post('/api/v1/comments', controller.v1.comments.create); // app/controller/v1/comments.js
};
注意事项
- 在 Router 定义中, 可以支持多个 Middleware 串联执行
- Controller 必须定义在
app/controller
目录中。 - 一个文件里面也可以包含多个 Controller 定义,在定义路由的时候,可以通过
${fileName}.${functionName}
的方式指定对应的 Controller。 - Controller 支持子目录,在定义路由的时候,可以通过
${directoryName}.${fileName}.${functionName}
的方式指定对应的 Controller。
参数获取
Query String 方式
// app/router.js
module.exports = app => {
app.router.get('/search', app.controller.search.index);
};
// app/controller/search.js
exports.index = async ctx => {
ctx.body = `search: ${ctx.query.name}`;
};
// curl http://127.0.0.1:7001/search?name=egg
参数命名方式
// app/router.js
module.exports = app => {
app.router.get('/user/:id/:name', app.controller.user.info);
};
// app/controller/user.js
exports.info = async ctx => {
ctx.body = `user: ${ctx.params.id}, ${ctx.params.name}`;
};
// curl http://127.0.0.1:7001/user/123/xiaoming
复杂参数的获取
路由里面也支持定义正则,可以更加灵活的获取参数:
// app/router.js
module.exports = app => {
app.router.get(/^\/package\/([\w-.]+\/[\w-.]+)$/, app.controller.package.detail);
};
// app/controller/package.js
exports.detail = async ctx => {
// 如果请求 URL 被正则匹配, 可以按照捕获分组的顺序,从 ctx.params 中获取。
// 按照下面的用户请求,`ctx.params[0]` 的 内容就是 `egg/1.0.0`
ctx.body = `package:${ctx.params[0]}`;
};
// curl http://127.0.0.1:7001/package/egg/1.0.0
表单内容的获取
// app/router.js
module.exports = app => {
app.router.post('/form', app.controller.form.post);
};
// app/controller/form.js
exports.post = async ctx => {
ctx.body = `body: ${JSON.stringify(ctx.request.body)}`;
};
// 模拟发起 post 请求。
// curl -X POST http://127.0.0.1:7001/form --data '{"name":"controller"}' --header 'Content-Type:application/json'
中间件
// app/controller/search.js
exports.index = async ctx => {
ctx.body = `search: ${ctx.query.name}`;
};
// app/middleware/uppercase.js
module.exports = () => {
return async function uppercase(ctx, next) {
ctx.query.name = ctx.query.name && ctx.query.name.toUpperCase();
await next();
};
};
// app/router.js
module.exports = app => {
app.router.get('s', '/search', app.middleware.uppercase(), app.controller.search)
};
// curl http://localhost:7001/search?name=egg