Egg框架三——基础功能
一、Router
1. router支持路由方式
支持一下路由格式:
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);
- router-name 给路由设定一个别名,可以通过 Helper 提供的辅助函数
pathFor
和urlFor
来生成 URL。(可选) - path-match - 路由 URL 路径。
- middleware1 - 在 Router 里面可以配置多个 Middleware。(可选)
- controller - 指定路由映射到的具体的 controller 上,controller 可以有两种写法:
app.controller.user.fetch
- 直接指定一个具体的 controller'user.fetch'
- 可以简写为字符串形式
2. RESTful 风格的 URL 定义
app.resources('routerName', 'pathMatch', controller)
快速在一个路径上生成 CRUD 路由结构。
例如:
// app/router.js
module.exports = app => {
const { router, controller } = app;
router.resources('posts', '/api/posts', controller.posts);
};
对应的路由路径如下所示:
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 |
3.获取参数
-
query string 方式获取:
search?name=egg
// 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
-
参数命名方式获取:
/user/123/xiaoming
// 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
-
表单内容获取
注意表单提交需要带上CSRF key 否则会报错
校验案例:
// app/router.js module.exports = app => { app.router.post('/user', app.controller.user); }; // app/controller/user.js const createRule = { username: { type: 'email', }, password: { type: 'password', compare: 're-password', }, }; exports.create = async ctx => { // 如果校验报错,会抛出异常 ctx.validate(createRule); ctx.body = ctx.request.body; }; // curl -X POST http://127.0.0.1:7001/user --data 'username=abc@abc.com&password=111111&re-password=111111'
4. 重定向
内部重定向
// app/router.js
module.exports = app => {
app.router.get('index', '/home/index', app.controller.home.index);
app.router.redirect('/', '/home/index', 302);
};
// app/controller/home.js
exports.index = async ctx => {
ctx.body = 'hello controller';
};
// curl -L http://localhost:7001
外部重定向
// app/router.js
module.exports = app => {
app.router.get('/search', app.controller.search.index);
};
// app/controller/search.js
exports.index = async ctx => {
const type = ctx.query.type;
const q = ctx.query.q || 'nodejs';
if (type === 'bing') {
ctx.redirect(`http://cn.bing.com/search?q=${q}`);
} else {
ctx.redirect(`https://www.google.co.kr/search?q=${q}`);
}
};
// curl http://localhost:7001/search?type=bing&q=node.js
// curl http://localhost:7001/search?q=node.js
4. 拆分路由
如果有太多路由可以如下拆分(不推荐拆分、会给排查问题带来麻烦):
// app/router.js
module.exports = app => {
require('./router/news')(app);
require('./router/admin')(app);
};
// app/router/news.js
module.exports = app => {
app.router.get('/news/list', app.controller.news.list);
app.router.get('/news/detail', app.controller.news.detail);
};
// app/router/admin.js
module.exports = app => {
app.router.get('/admin/user', app.controller.admin.user);
app.router.get('/admin/log', app.controller.admin.log);
};
也可直接使用 egg-router-plus。