inversify-restify-utils

原文链接

一些方便使用InversifyJS开发REST应用的工具。

安装

您可以使用npm来安装inversify-restify-utils

npm install inversify inversify-restify-utils reflect-metadata --save
1

inversify-restify-utils类型定义包含在了npm模块中,TypeScript版本要求是2.0以上。请参阅InversifyJS文档以了解更多关于安装过程的信息。

基础

第一步:装饰您的控制器

要想将类作为REST应用的“控制器”,只需向类中添加@Controller装饰器即可。同理可将类的方法修饰为请求句柄。下面的示例展示的是声明GET /foo的控制器:

import { Request } from 'restify';
import { Controller, Get, interfaces } from 'inversify-restify-utils';
import { injectable, inject } from 'inversify';

@Controller('/foo')
@injectable()
export class FooController implements interfaces.Controller {
    
    constructor( @inject('FooService') private fooService: FooService ) {}
    
    @Get('/')
    private index(req: Request): string {
        return this.fooService.get(req.query.id);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

第二步:配置容器和服务器

像往常一样在您的根文件中配置反转容器。

接下来,将容器传入InversifyRestifyServer构造器中。这样就将容器中所有的控制器及其依赖项进行了注册,并将其附加到REST应用中。接下来调用server.build()启动服务。

为了确保InversifyRestifyServer能够找到你的控制器,请务必绑定TYPE.Controller并将控制器名称作为其标签。本框架导出的Controller接口其实是空的,仅仅为了方便开发,如果您想配置您自己的接口也没有问题。

import { Container } from 'inversify';
import { interfaces, InversifyRestifyServer, TYPE } from 'inversify-restify-utils';

// set up container
let container = new Container();

// note that you *must* bind your controllers to Controller 
container.bind<interfaces.Controller>(TYPE.Controller).to(FooController).whenTargetNamed('FooController');
container.bind<FooService>('FooService').to(FooService);

// create server
let server = new InversifyRestifyServer(container);

let app = server.build();
app.listen(3000);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

服务器配置项可以作为第二个参数传入InversifyRestifyServer构造器:

let server = new InversifyRestifyServer(container, { name: "my-server" });
1

其中可以配置defaultRoot来定义所有控制器的默认路径:

let server = new InversifyRestifyServer(container, { name: "my-server", defaultRoot: "/v1" });
1

InversifyRestifyServer

它是对REST服务的封装。

.setConfig(configFn)

配置项 —— 暴露REST应用对象,以方便加载服务器级别的中间件。

import * as morgan from 'morgan';
// ...
let server = new InversifyRestifyServer(container);
server.setConfig((app) => {
    var logger = morgan('combined')
    app.use(logger);
});
1
2
3
4
5
6
7

.build()

将所有注册的控制器和中间件连接到REST应用。返回应用的实例。

// ...
let server = new InversifyRestifyServer(container);
server
    .setConfig(configFn)
    .build()
    .listen(3000, 'localhost', callback);
1
2
3
4
5
6

装饰器

@Controller(path, [middleware, ...])

将所装饰的类注册为具有根路径的控制器,并且可以为该控制器注册任意的全局中间件。

@Method(method, path, [middleware, ...])

将所装饰的控制器方法注册为特定路径和请求方式的请求句柄,需要注意的是方法名应该是合法的REST路由方法。

@SHORTCUT(path, [middleware, ...])

Shortcut装饰器是对@httpMethod的简单封装。它包括了@Get,@Post@Put@Patch@Head@Delete@Options。如果想要这之外的功能,请使用Method(或者给我们提个PR 😄)。

中间件

中间件可以是restify.RequestHandler的实例,也可以是InversifyJS服务标识符。

使用中间件最简单的方法是定义restify.RequestHandler实例并将句柄作为装饰器参数传入。

// ...
const loggingHandler = (req: restify.Request, res: restify.Response, next: restify.Next) => {
  console.log(req);
  next();
};

@Controller('/foo', loggingHandler)
@injectable()
export class FooController implements interfaces.Controller {
    
    constructor( @inject('FooService') private fooService: FooService ) {}
    
    @Get('/', loggingHandler)
    private index(req: restify.Request): string {
        return this.fooService.get(req.query.id);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

但是,如果您希望充分利用InversifyJS,可以将相同的句柄绑定到IOC容器,并将其服务标识符传递给装饰器。

// ...
import { TYPES } from 'types';
// ...
const loggingHandler = (req: restify.Request, res: restify.Response, next: restify.Next) => {
  console.log(req);
  next();
};
container.bind<restify.RequestHandler>(TYPES.LoggingMiddleware).toConstantValue(loggingHandler);
// ...
@Controller('/foo', TYPES.LoggingMiddleware)
@injectable()
export class FooController implements interfaces.Controller {
    
    constructor( @inject('FooService') private fooService: FooService ) {}
    
    @Get('/', TYPES.LoggingMiddleware)
    private index(req: restify.Request): string {
        return this.fooService.get(req.query.id);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
上次更新: 1/14/2020, 4:49:04 PM