Egg.js 路由装饰器,让你的开发更敏捷~
【掘金原文】:egg-shell-decorators 给你的蛋蛋加个壳 【PS:不知道为什么CNode的文本渲染会在装饰器前后加上方括号。。文末有本人联系方式,欢迎技术交流~】
egg-shell-decorators 是一个 Egg.js 的插件,它提供了一系列的 Decorator 装饰 Controller,让我们先来看一个例子:
// app/controller/user
import { Controller } from 'egg';
import { Get, Message } from 'egg-shell-decorators';
export default class UserController extends Controller {
[@Get](/user/Get)('/detail/:id')
@Message('so great !')
public async get({ params: { id } }) {
return await this.service.user.getById(id)
}
}
上面是一个简单的控制器例子,如果是 egg.js 的默认开发方式,那么你得在 router 文件对相应的路由进行映射,而使用 egg-shell-decorators 之后,再也不用在 router 文件进行任何路由匹配了。因为 egg-shell-decorators 的路由解析
会自动对路由进行解析,像上面这个例子会自动解析成 [get] 全局前缀 + /user/detail/:id
,这样我们开发者就不用再去操心映射的问题了,而且在 Controller 里我们就可以知道每一个函数对应的请求信息。
也许你会疑惑上面的@Message
还有为什么直接把查询到的数据 return 了
是怎么回事,现在我将系统的向你介绍该插件的使用:
Installation
$ npm install egg-shell-decorators -S
如果不是采用 TypeScript 脚手架,则需执行以下脚本安装相关的 Babel 插件:
$ npm install babel-register babel-plugin-transform-decorators-legacy -D
Usage
示范代码均采用 TypeScript
// app/router.ts
import { Application } from 'egg';
import { EggShell } from 'egg-shell-decorators';
export default (app: Application) => {
EggShell(app, { prefix: '/', quickStart: true });
};
配置参数:
prefix: string // 全局前缀
quickStart: boolean // 开启QuickStart
如果不是采用 TypeScript 脚手架,则需在入口注册 Bable 插件使其支持 Decorator:
// app.js
'use strict';
require('babel-register')({
plugins: [
'transform-decorators-legacy',
],
});
Specialty
路由解析
是 egg-shell-decorators 最大的特点,使用 Decorator 装饰的路由,则会被自动解析成对应的路由:
- 文件路径:
app/controller/home.ts
- 解析路由:
[get] 全局前缀 + /home + /detail/:id
[post] 全局前缀 + /home + /
这里的 全局前缀 指的是你在 EggShell 里配置的 prefix
,路由解析支持多层级解析噢
~
Member
- Http相关
- ✅Get
- ✅Post
- ✅Put
- ✅Delete
- ✅Patch
- ✅Options
- ✅Head
- 🔲Header
- 中间件相关
- ✅Before
- ✅After
- ✅BeforeAll
- ✅AfterAll
- Swagger相关
- 🔲敬请期待下一个版本
- 其他
- ✅Prefix
- ✅Message
- ✅IgnoreJwt
- ✅IgnoreJwtAll
Prefix
如果你不喜欢路由解析
给你的路径,那么你可以自定义解析的路径:
// app/controller/user
import { Controller } from 'egg';
import { Get, Message, Prefix } from 'egg-shell-decorators';
@Prefix('/super2god')
export default class UserController extends Controller {
[@Get](/user/Get)('/detail/:id')
@Message('so great !')
public async get({ params: { id } }) {
return await this.service.user.getById(id)
}
}
这样解析出来的路由就是:全局前缀 + /super2god/detail/:id
,而不是全局前缀 + /user/detail/:id
QuickStart
在 EggShell 里配置 quickStart
为 true 即可开启 QuickStart 模式,QuickStart 模式会自动处理响应体:
import { Controller } from 'egg';
import { Get, Message, Error, StatusError } from 'egg-shell-decorators';
export default class UserController extends Controller {
/**
status: 200
{
success: true,
message: '棒棒哒',
data: {
id: '123',
name: 'super2god'
},
}
*/
[@Get](/user/Get)('/:id')
@Message('棒棒哒')
public async get({ params: { id } }) {
return await this.service.user.getById(id)
}
/**
status: 200
{
success: false,
message: '故意的'
}
*/
[@Post](/user/Post)('/:id')
public post() {
throw Error('故意的')
}
/**
status: 403
{
success: false,
message: '权限不足'
}
*/
[@Post](/user/Post)('/:id')
public post() {
// StatusError 的第二个参数默认值为500
throw StatusError('权限不足', 403)
}
}
RESTful
让我们用 egg-shell-decorators 快速写一套 RESTful 风格的接口(QuickStart 模式):
import { Controller } from 'egg';
import { Get, Post, Put, Delete } from 'egg-shell-decorators';
export default class SubOrderController extends Controller {
[@Get](/user/Get)('/:id')
public get({ params: { id }, query: { keyword } }) {
return `resuful get : ${id}, ${keyword}`;
}
[@Post](/user/Post)('/:id')
public post({ params: { id }, request: { body: { keyword } } }) {
return `resuful post : ${id}, ${keyword}`;
}
@Put('/:id')
public put({ params: { id }, request: { body: { keyword } } }) {
return `resuful put : ${id}, ${keyword}`;
}
@Delete('/:id')
public delete({ params: { id }, request: { body: { keyword } } }) {
return `resuful delete : ${id}, ${keyword}`;
}
}
由于 egg-shell-decorators 内置把 ctx
对象传进 Controller 的函数里了,所以我们直接结构就可以获取到请求参数了,美滋滋~
当然,除了这四个常用的请求方法,egg-shell-decorators 还提供了其他比较常用的请求方法,具体请看上面的Http请求方法
。
Jwt
Jwt是目前比较流行的身份认证机制,所以 egg-shell-decorators 提供了相关的 Decorator。如果你使用了 egg-jwt
,那默认所以路由都需要进行身份校验,而有时我们想让部分路由不用校验,那么你只需那么做:
import { Controller } from 'egg';
import { Get, IgnoreJwt } from 'egg-shell-decorators';
export default class HomeController extends Controller {
@IgnoreJwt
[@Get](/user/Get)('/')
public async index() {
return 'hi, egg';
}
}
是不是很简单呢,如果你想对整个 Controller 都进行校验忽略,那也很简单:
import { Controller } from 'egg';
import { Get, Post, IgnoreJwtAll } from 'egg-shell-decorators';
@IgnoreJwtAll
export default class HomeController extends Controller {
[@Get](/user/Get)('/')
public async get() {
return 'get';
}
[@Post](/user/Post)('/')
public async post() {
return 'post';
}
}
MiddleWare
egg-shell-decorators 提供了四个中间件相关的 Decorator,让你使用中间件更简单:
import { Controller } from 'egg';
import { Get, IgnoreJwtAll, Before, After, BeforeAll, AfterAll } from 'egg-shell-decorators';
const Before1 = require('egg-shell-decorators/test/middlewares/before-1');
const Before2 = require('egg-shell-decorators/test/middlewares/before-2');
const Before3 = require('egg-shell-decorators/test/middlewares/before-3');
const Before4 = require('egg-shell-decorators/test/middlewares/before-4');
const After1 = require('egg-shell-decorators/test/middlewares/after-1');
const After2 = require('egg-shell-decorators/test/middlewares/after-2');
const After3 = require('egg-shell-decorators/test/middlewares/after-3');
const After4 = require('egg-shell-decorators/test/middlewares/after-4');
@BeforeAll([ Before1, Before2 ])
@AfterAll([ After1, After2 ])
@IgnoreJwtAll
export default class HomeController extends Controller {
/**
before middleware => 1
before middleware => 2
before middleware => 3
before middleware => 4
主业务...
after middleware => 1
after middleware => 2
after middleware => 3
after middleware => 4
*/
@Before([ Before3, Before4 ])
@After([ After3, After4 ])
[@Get](/user/Get)('/')
public async index() {
return 'hi, egg';
}
}
egg-shell-decorators 的用法都已经介绍完毕了,如果你是一名 Noder 或者热爱 Egg.js 的小伙伴,那么可以加我微信进行技术交流,让我们一起变得更优秀:
赞
酷,有种想开发几个feature了,像 java spring那样的 注解, 用ts,我先用一下,感受一下先。
赞~
👍
@CareyToboo 阿哈,最近有朋友反馈windows路由会解析不了,这是个bug,我周末更新一个版本处理一下~
@atian25 谢谢
@dengnan123 谢谢
@atzcl 谢谢