项目地址: https://github.com/loon-project/loon
抄一段我写在文档里面的代码。
// 定义一个事件发布者
@Service()
class CustomEventEmitter extends EventEmitter {}
// 定义一个事件订阅者
@Subscriber()
class CustomEventSubscriber {
private property = "a property";
// 用 `On` 注册了 `newEvent` 事件的回调
@On('newEvent', CustomEventEmitter)
public onEventEmit() {
this.property === "a property" // => true
}
}
const emitter = DependencyRegistry.get(CustomEventEmitter);
emitter.emit('newEvent');
当事件发布者发布一个消息时,事件订阅者马上会触发注册的方法。 <br> <b>重要: 在订阅者方法中的this是订阅者本身</b>
上次发的介绍框架其他细节的帖子内容
一个类似于springmvc的nodejs框架,内置了常用的express包,有丰富的可选配置,依赖注入. 项目地址 文档
功能
- 依赖注入
- 服务类
- Result 路由和控制器
- 中间件
- 过滤器
- 模型
- 转化器
- 启动器
快速开始
<br>
- 克隆 loon-boilerplate 项目
$ git clone https://github.com/loon-project/loon-boilerplate
$ cd loon-boilerplate
$ npm install
- 开始编译typescript并启动服务器
$ npm run dev
- 在浏览器中测试 http://localhost:9000
控制器
@RestController('/admin')
class AdminController {
@Get('/users/:id')
public userAction(@PathParam('id') id: number) {
# incoming request is /admin/users/1
# then id inside this action would be 1
}
@Get('/users')
public listUsersAction(@QueryParam('is_active') isActive: boolean) {
# incoming request is /admin/users?is_active=true
# then isActive inside this action would be true
isAction === true # => true
}
@Post('/users')
public createUserAction(@BodyParam('user') user: any) {
# incoming request is POST /admin/users with json body
# {
# user: {name: "Jack"}
# }
# then the user inside this action would be a object
user.name === "Jack" # => true
}
}
过滤器
AuthenticateFilter
前置过滤器检查是否用户已经登陆,
如果用户还没有登陆, 就直接返回 403 状态码。
使用时 AuthenticatedResourceController
加上一个 @BeforeFilter(AuthenticateFilter)
的注解,
这就意味着所有这个 Controller 里面的 路由都会使用前置过滤器 AuthenticateFilter
。
如果这个 Controller 需要几个能让匿名用户访问的路由, 可以在使用注解时加上参数来达到部分使用过滤器的目的。
@Filter()
class AuthenticateFilter implements IMiddleware {
public use(@Res() res: Express.Response, @Next() next: Express.NextFunction) {
if (// use is logged in) {
next();
} else {
res.sendStatus(403);
}
}
}
@RestController()
@BeforeFilter(AuthenticateFilter)
class AuthenticatedResourceController {}
中间件
注解了 @Middleware
并且实现了 IMiddleware
的类自动会识别并加载为 Middleware
。
@Middleware({order: 0})
class ELKMiddleware implements IMiddleware {
public use(@Next() next: Express.NextFunction) {
// start tracking
next()
// end tracking
// send to elk
}
}
错误中间件
@ErrorMiddleware
用法和 @Middleware
基本一样, 有一个不同点是你能通过 @Err
拿到错误 Object。
@ErrorMiddleware()
class ExceptionHandler implements IMiddleware {
public use(@Err() err: any, @Res() res: Express.Response) {
console.log(err.message);
res.sendStatus(400);
}
}
模型
模型通过添加 @Property
注解增加了转化的能力。
class User {
@Property()
firstName: string;
@Property()
lastName: string;
}
@RestController("/users")
class UserController {
@Post("")
public createAction(@BodyParam('user') user: User) {
user instanceof User # => true
}
}
控制器中的参数 user
制定了类是 User
, 当带有 http body 的请求到来时:
{
user: {
firstName: "Jack",
lastName: "Hai"
}
}
user 这个变量会自动的转化成 User
model 的实例。
自定义转化器
属性也支持传一个实现了 IConverter
借口的类作为自定义转化器。
@Service()
export class MomentConverter implements IConverter {
public deserialize(data: any, klassProperty: string, objectProperty: string): any {
const value = data[objectProperty];
if (typeof value === 'undefined') {
return;
}
const m = Moment.utc(value);
if (m.isValid()) {
return m;
}
return;
}
}
class User {
@Property({converter: MomentConverter})
public registerDate: Moment.Moment;
}
这个例子显示了如何写一个转化 string/Date
对象到 moment
utc 对象。
服务
@Service()
class UserService {
// any logic
}
@RestController('/users')
class UserController {
@Inject()
private userService: UserService;
@Get('')
public indexAction() {
this.userService.listUsers();
}
}
在例子中, UserService
注解了 @Service
, 然后被注入在了 UserController
。
文档更多详细的说明
欢迎star,fork还有各种issues 项目地址