Skip to content
This repository has been archived by the owner on Aug 28, 2023. It is now read-only.

Commit

Permalink
feat: plugin can be configured by pluginName or plugin class name and…
Browse files Browse the repository at this point in the history
… docs update
  • Loading branch information
amazing-gao committed Feb 5, 2018
1 parent bdf5a7a commit 825646d
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 93 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -132,7 +132,7 @@ const router = new Router({

// *configure plugin - identify x-oai-middleware in the api file and load the appropriate middleware from controllers
// *mount plugin to router
router.mount(middleware('./controllers'));
router.mount(middleware, './controllers');

app.use(logger());
app.use(bodyParser());
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Expand Up @@ -131,7 +131,7 @@ const router = new Router({

// *配置插件 - 识别api文档中的x-oai-middleware并从controllers中加载相应的中间件
// *挂载插件到router
router.mount(middleware('./controllers'));
router.mount(middleware, './controllers');

app.use(logger());
app.use(bodyParser());
Expand Down
136 changes: 93 additions & 43 deletions docs/en/references.md
Expand Up @@ -3,7 +3,7 @@

* [Router](#router)
* [new Router(options)](#new-routeroptions)
* [router.mount(Plugin)](#routermountplugin)
* [router.mount(Plugin, pluginArgs)](#routermountplugin-pluginargs)
* [router.get|put|post|patch|delete|del](#routergetputpostpatchdeletedel)
* [router.routes()](#routerroutes)
* [router.use([path], middleware)](#routerusepath-middleware)
Expand All @@ -14,7 +14,11 @@
* [router.param(param, middleware)](#routerparamparam-middleware)
* [Router.url(path, params)](#routerurlpath-params)
* [Plugin](#plugin)
* [new Plugin(options)](#new-pluginoptions)
* [constructor(args)](#constructorargs)
* [init()](#init)
* [before(docOpts)](#beforedocopts)
* [handler(docOpts)](#handlerdocopts)
* [after(docOpts)](#afterdocopts)

<!-- /code_chunk_output -->

Expand Down Expand Up @@ -75,7 +79,7 @@ app.use(router.routes());
app.listen(3000);
```

## router.mount(Plugin)
## router.mount(Plugin, pluginArgs)
Mount the plugin to the router, the plugin will be executed with order of mount.
If one of the plugins does not evoke next(), execution of the subsequent plugin chain will be terminated.

Expand Down Expand Up @@ -107,64 +111,110 @@ Same as koa-router: [router.param(param, middleware)][router-param]
Same as koa-router: [Router.url(path, params)][Router-url]



# Plugin
Plugins can be applied to every api as koa middleware.
Its activation depends on whether the api document contains its activation `field`. Once the plugin is activated, `middlewareWrapper` will be invoked internally and passed in the `(middlewareOpts, middlewareArgs)` parameter and must return a koa middleware that will be mounted on the current api.

## new Plugin(options)
Create a plugin.

* `options` {object} Plugin configuration options. Can have the following fields:
* `name` {string} `required` The name of the plugin. Configure the plugin parameters in the router options as the key.
* `field` {string|string[]} `required` Activate field. The plugin is activated when this field is included in the API document. Field range reference [Operation Object][oai-fields].
* `middlewareWrapper` {object} `required` Plugin logic module, you must return a koa middleware.
* `middlewareArgs` {object} `optional` Plugin global options.
Its activation depends on whether the api document contains its activation `field`. Once the plugin is activated, `handler` will be invoked internally and passed in the `(docOpts)` parameter and must return a koa middleware that will be mounted on the current api.

`middlewareWrapper` Must return a koa middleware, there (middlewareOpts, middlewareArgs) Parameters:
* `middlewareOpts` {object} Information about the current interface document fragment when the plug-in is activated.
* `endpoint` {string} ednpoint
* `field` {string} the keyword when activated
* `fieldValue` {object} The data corresponding to the keyword when it is activated
* `operation` {string} http method
* `operationValue` {object} api's meta data
* `middlewareArgs` {any} Plugin global options.

`middlewareArgs` can be configured when creating a router and the configuration of this method will have the highest priority.
`pluginArgs` can be configured when creating a router and the configuration of this method will have the highest priority.
```js
const plugin = new PluginXXX({
name: 'pluginXXX',
field: 'parameters',
// middlewareArgs: pluginArgs,
middlewareWrapper: () => {
return (ctx, next) => {return next();};
},
});
class PluginX extends Plugin {
constructor() {
super();

this.pluginName = 'tags';
this.field = 'tags';
this.after = undefined;
}
handler({ fieldValue }) {
return (ctx, next) => {
// what do you want to do.
};
}
}

// PluginName and Plugin class name both can be config for arguments
const router = new Router({
apiDoc: './api',
options: {
pluginXXX: pluginArgs,
PluginX: pluginArgs,
// OR
tags: pluginArgs
}
});

router.mount(plugin);
router.mount(PluginX);
```

`middlewareArgs` it can also be configured when creating a plugin, and the method's configuration will have the lowest priority.

`pluginArgs` it can also be configured when creating a plugin, and the method's configuration will have the lowest priority.
```js
const plugin = new PluginXXX({
name: 'pluginXXX',
field: 'parameters',
middlewareArgs: pluginArgs,
middlewareWrapper: () => {
return (ctx, next) => {return next();};
},
});
class PluginX extends Plugin {
constructor() {
super();

this.pluginName = 'tags';
this.field = 'tags';
this.after = undefined;
}
handler({ fieldValue }) {
return (ctx, next) => {
// what do you want to do.
};
}
}

const router = new Router({
apiDoc: './api',
});

router.mount(plugin);
router.mount(plugin, pluginArgs);
```


## constructor(args)
Must set these properties in constructor: `pluginName`, `field`, `args`.
* `pluginName` `string` `required` name of plugin
* `fields` `string|string[]` `required` invoked fields
* `args` `any` `optional` args of plugin

## init()
Called when plugin is initializing and called before `before`. Only called once, suit for prepare works.

`optional` implemented

## before(docOpts)
Previous works for plugin, called before `handler`.

`optional` implemented

* `docOpts` {object} Information about the current interface document fragment when the plug-in is activated.
* `endpoint` {string} ednpoint
* `field` {string} the keyword when activated
* `fieldValue` {object} The data corresponding to the keyword when it is activated
* `operation` {string} http method
* `operationValue` {object} api's meta data

## handler(docOpts)
Main works for plugin.

`required` implemented, must return a koa middleware function, eg: `function(ctx, next) {}`.

* `docOpts` {object} Information about the current interface document fragment when the plug-in is activated.
* `endpoint` {string} ednpoint
* `field` {string} the keyword when activated
* `fieldValue` {object} The data corresponding to the keyword when it is activated
* `operation` {string} http method
* `operationValue` {object} api's meta data

## after(docOpts)
Post works for plugin, called after `handler`.

`optional` implemented

* `docOpts` {object} Information about the current interface document fragment when the plug-in is activated.
* `endpoint` {string} ednpoint
* `field` {string} the keyword when activated
* `fieldValue` {object} The data corresponding to the keyword when it is activated
* `operation` {string} http method
* `operationValue` {object} api's meta data
135 changes: 92 additions & 43 deletions docs/zh/references.md
Expand Up @@ -3,7 +3,7 @@

* [Router](#router)
* [new Router(options)](#new-routeroptions)
* [router.mount(Plugin)](#routermountplugin)
* [router.mount(Plugin, pluginArgs)](#routermountplugin-pluginargs)
* [router.get|put|post|patch|delete|del](#routergetputpostpatchdeletedel)
* [router.routes()](#routerroutes)
* [router.use([path], middleware)](#routerusepath-middleware)
Expand All @@ -14,7 +14,11 @@
* [router.param(param, middleware)](#routerparamparam-middleware)
* [Router.url(path, params)](#routerurlpath-params)
* [Plugin](#plugin)
* [new Plugin(options)](#new-pluginoptions)
* [constructor(args)](#constructorargs)
* [init()](#init)
* [before(docOpts)](#beforedocopts)
* [handler(docOpts)](#handlerdocopts)
* [after(docOpts)](#afterdocopts)

<!-- /code_chunk_output -->

Expand Down Expand Up @@ -77,7 +81,7 @@ app.use(router.routes());
app.listen(3000);
```

## router.mount(Plugin)
## router.mount(Plugin, pluginArgs)
将插件挂载到router上,先挂载的插件先被执行。如果其中一个插件未唤起next(),那么后续插件链的执行将被结束。

## router.get|put|post|patch|delete|del
Expand Down Expand Up @@ -110,62 +114,107 @@ Same as koa-router: [Router.url(path, params)][Router-url]

# Plugin
插件是可以应用在每一个接口上的koa中间。
它的激活取决于该接口描述文档中是否包含它的`激活字段(field)`。一旦插件被激活,那么`middlewareWrapper`将在内部被调用,并传入(middlewareOpts, middlewareArgs)参数,且必须返回一个koa中间件,该中间件将被挂载到当前接口上。
它的激活取决于该接口描述文档中是否包含它的`激活字段(field)`。一旦插件被激活,那么`handler`将在内部被调用,并传入`(docOpts)`参数,且必须返回一个koa中间件,该中间件将被挂载到当前接口上。

## new Plugin(options)

* `options` {object} 插件的配置选项。有以下字段:
* `name` {string} `必须` 插件的名称。在路由的`options`中配置插件参数时作为key。
* `field` {string|string[]} `必须` 激活字段。当API文档中包含该字段时插件被激活。字段范围参考[Operation Object][oai-fields]
* `middlewareWrapper` {object} `必须` 插件逻辑模块,必须返回一个koa中间件。
* `middlewareArgs` {object} `可选` 插件的全局选项。

创建一个Router的插件。

`middlewareWrapper`必须返回一个koa中间件,有(middlewareOpts, middlewareArgs)参数:
* `middlewareOpts` {object} 插件被激活时当前接口文档片段的信息。
* `endpoint` {string} 接口的路径
* `field` {string} 被激活时的关键字
* `fieldValue` {object} 被激活时的关键字对应的数据
* `operation` {string} 接口的方法
* `operationValue` {object} 接口的描述信息
* `middlewareArgs` {any} 插件的全局选项。

`middlewareArgs`可以在创建router时配置,本方法的配置将拥有最高优先级。
`pluginArgs`可以在创建router时配置,本方法的配置将拥有最高优先级。
```js
const plugin = new PluginXXX({
name: 'pluginXXX',
field: 'parameters',
// middlewareArgs: pluginArgs,
middlewareWrapper: () => {
return (ctx, next) => {return next();};
},
});
class PluginX extends Plugin {
constructor() {
super();

this.pluginName = 'tags';
this.field = 'tags';
this.after = undefined;
}
handler({ fieldValue }) {
return (ctx, next) => {
// what do you want to do.
};
}
}

// PluginName and Plugin class name both can be config for arguments
const router = new Router({
apiDoc: './api',
options: {
pluginXXX: pluginArgs,
PluginX: pluginArgs,
// OR
tags: pluginArgs
}
});

router.mount(plugin);
router.mount(PluginX);
```

`middlewareArgs`也可以在创建插件时配置,本方法的配置将拥有最低的优先级。
`pluginArgs`也可以在创建插件时配置,本方法的配置将拥有最低的优先级。
```js
const plugin = new PluginXXX({
name: 'pluginXXX',
field: 'parameters',
middlewareArgs: pluginArgs,
middlewareWrapper: () => {
return (ctx, next) => {return next();};
},
});
class PluginX extends Plugin {
constructor() {
super();

this.pluginName = 'tags';
this.field = 'tags';
this.after = undefined;
}
handler({ fieldValue }) {
return (ctx, next) => {
// what do you want to do.
};
}
}

const router = new Router({
apiDoc: './api',
});

router.mount(plugin);
router.mount(plugin, pluginArgs);
```


## constructor(args)
在构造函数请设置参数:`pluginName`, `field`, `args`
* `pluginName` `string` `optional` 插件名称,用于配置插件参数。如果不设置默认使用插件类名称。
* `fields` `string|string[]` `required` 插件的激活字段
* `args` `any` `optional` 插件的参数

## init()
在插件初始化时调用,在`before`之前。插件生命周期中只执行一次,适合做一些插件启动工作。

`可选`实现

## before(docOpts)
插件的前置业务逻辑,在`handler`之前执行,

`可选`实现

* `docOpts` {object} 插件被激活时当前接口文档片段的信息。
* `endpoint` {string} 接口的路径
* `field` {string} 被激活时的关键字
* `fieldValue` {object} 被激活时的关键字对应的数据
* `operation` {string} 接口的方法
* `operationValue` {object} 接口的描述信息

## handler(docOpts)
插件的主要业务逻辑。

`必须`实现,且要求返回koa中间件,形如:`function(ctx, next) {}`

* `docOpts` {object} 插件被激活时当前接口文档片段的信息。
* `endpoint` {string} 接口的路径
* `field` {string} 被激活时的关键字
* `fieldValue` {object} 被激活时的关键字对应的数据
* `operation` {string} 接口的方法
* `operationValue` {object} 接口的描述信息

## after(docOpts)
插件的后置业务逻辑,在`handler`之后执行,

`可选`实现

* `docOpts` {object} 插件被激活时当前接口文档片段的信息。
* `endpoint` {string} 接口的路径
* `field` {string} 被激活时的关键字
* `fieldValue` {object} 被激活时的关键字对应的数据
* `operation` {string} 接口的方法
* `operationValue` {object} 接口的描述信息

0 comments on commit 825646d

Please sign in to comment.