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

Commit

Permalink
Merge pull request #26 from BiteBit/dev
Browse files Browse the repository at this point in the history
Support swagger-ui 3.x
  • Loading branch information
amazing-gao committed May 3, 2017
2 parents c5e0096 + 2e0f67d commit 01479d3
Show file tree
Hide file tree
Showing 9 changed files with 438 additions and 15 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -3,5 +3,6 @@ node_js:
- "4"
- "5"
- "6"
- "7"
script: "npm run test-travis"
after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"
129 changes: 123 additions & 6 deletions README.md
Expand Up @@ -58,7 +58,10 @@ I truly hope that this library can help those who are in the same trouble. Happy
- [apiExplorerStaticPath](#apiexplorerstaticpath)
- [jsonSchemaFormatters](#jsonschemaformatters)
- [errorHandler](#errorhandler)
- [defaultResponseSchemas](#defaultResponseSchemas)
- [defaultResponseSchemas](#defaultresponseschemas)
- [Router.routes()](#routerroutes)
- [Router.apiExplorer()](#routerapiexplorer)
- [Router.apiExplorerV3()](#routerapiexplorerv3)
- [Router.use(keyword, fn)](#routerusekeyword-fn)
- [Router.extend(endpoint, fn)](#routerextendendpoint-fn)
- [Contrller](#contrller)
Expand All @@ -75,8 +78,6 @@ I truly hope that this library can help those who are in the same trouble. Happy

---

**<u>Notice:Testing stage,Production not recommend!!!</u>**

# Features
* Built-in Swagger-UI, easy view and debug
* Auto generate route by OpenAPI/Swagger api doc, and validate parameters
Expand Down Expand Up @@ -396,11 +397,126 @@ You can design your custom error handler by doing this. The function has paramet

### defaultResponseSchemas

TODO
Define default response schemas, if you don't want to write response schema under every api.

```js
const commonSchema = {
type: 'object',
properties: {
error_code: {
type: 'number',
},
error_description: {
type: 'string',
},
},
};

const schemas = {
401: {
title: 'Unauthorized',
schema: commonSchema,
},
402: {
title: 'PaymentRequired',
schema: commonSchema,
},
403: {
title: 'Forbidden',
schema: commonSchema,
},
404: {
title: 'NotFound',
schema: commonSchema,
},
429: {
title: 'TooManyRequests',
schema: commonSchema,
},
500: {
title: 'InternalError',
schema: commonSchema,
},
};
```

## Router.routes()

Return router middleware which dispatches a route matching the request.

## Router.apiExplorer()

Return router middleware which mounts swagger-ui 2.x. Open **/api-explorer** to explorer you api.

## Router.apiExplorerV3()

Return router middleware which mounts swagger-ui 3.x. Open **/api-explorer-v3** to explorer you api. swagger-ui 3.x supports 2.x specification.

## Router.use(keyword, fn)

TODO
Through this, you can extend plugin to handle options which starts with **x-oai-** in apiDoc.

* keyword starts with **x-oai-** , not including **x-oai-controller**.
* fn is handler of keywords.

For example,we need to configure cache expired time for api through apiDoc. We can extend plugin based on following steps.

```yaml
# First,configure cache expired time at apiDoc.
# x-oai-cache:
# expire: 86400
# api.yaml

/users/{userId}:
get:
tags:
- User
description: find a user by userId
x-oai-cache:
expire: 86400
x-oai-controller:
- file: people
handler: get
parameters:
- name: userId
in: path
required: true
type: number
responses:
default:
description: unexpected error
schema:
$ref: '#/definitions/Error'
```

```js
/*
* Second,develop x-oai-cahce plugin.
* Export a function with a argument, and return a koa middleware.
*/
export default (config) => {
// config is {expire: 86400}
return (ctx, next) => {
// write your code.
}
}
```

```js
/*
* Third,mount your plugin to router with keyword.
*/
var router = new Router(opt);

var cachePlugin = new Cache({
store: new Redis()
});

router.use('x-oai-cache', cachePlugin);

app.use(router.routes());
app.use(router.apiExplorer());
```

## Router.extend(endpoint, fn)

Expand Down Expand Up @@ -633,7 +749,8 @@ When page is not inputed, the api will send HTTP 400 with the response body hand


# Plan
* Support OpenAPI/Swagger1.x
* ~~Support OpenAPI/Swagger1.x~~
* Support OpenAPI/Swagger3.0
* Support OpenAPI/Swagger2.0 Security keyword
* Support Response validate
* Research more Json Schema validator
Expand Down
133 changes: 127 additions & 6 deletions README.zh-CN.md
Expand Up @@ -35,8 +35,6 @@

*哦,对了,PR & Issue & Star are welcome! : )*

**<u>注意:目前仍然处于测试阶段,生产环境谨慎使用!!!</u>**

---

- [Koa-OAI-Router](#koa-oai-router)
Expand All @@ -60,7 +58,10 @@
- [apiExplorerStaticPath](#apiexplorerstaticpath)
- [jsonSchemaFormatters](#jsonschemaformatters)
- [errorHandler](#errorhandler)
- [defaultResponseSchemas](#defaultResponseSchemas)
- [defaultResponseSchemas](#defaultresponseschemas)
- [Router.routes()](#routerroutes)
- [Router.apiExplorer()](#routerapiexplorer)
- [Router.apiExplorerV3()](#routerapiexplorerv3)
- [Router.use(keyword, fn)](#routerusekeyword-fn)
- [Router.extend(endpoint, fn)](#routerextendendpoint-fn)
- [接口的控制器](#%E6%8E%A5%E5%8F%A3%E7%9A%84%E6%8E%A7%E5%88%B6%E5%99%A8)
Expand Down Expand Up @@ -393,11 +394,130 @@ function 可选 [默认处理函数](#)

### defaultResponseSchemas

TODO
定义一个默认的响应schema。

```js
const commonSchema = {
type: 'object',
properties: {
error_code: {
type: 'number',
},
error_description: {
type: 'string',
},
},
};

const schemas = {
401: {
title: 'Unauthorized',
schema: commonSchema,
},
402: {
title: 'PaymentRequired',
schema: commonSchema,
},
403: {
title: 'Forbidden',
schema: commonSchema,
},
404: {
title: 'NotFound',
schema: commonSchema,
},
429: {
title: 'TooManyRequests',
schema: commonSchema,
},
500: {
title: 'InternalError',
schema: commonSchema,
},
};
```





## Router.routes()

Return router middleware which dispatches a route matching the request.

## Router.apiExplorer()

Return router middleware which mounts swagger-ui 2.x. Open **/api-explorer** to explorer you api.

## Router.apiExplorerV3()

Return router middleware which mounts swagger-ui 3.x. Open **/api-explorer-v3** to explorer you api. swagger-ui 3.x support 2.x specification

## Router.use(keyword, fn)

TODO
通过此你可以为router设置插件,自定义处理apiDoc中的以**x-oai-**开头的选项。

* keyword是以**x-oai-**开头且不是**x-oai-controller**的字符串
* fn对应keyword的处理器

例如,我们需要通过apiDoc配置指定接口的缓存时间,我们可以通过如下步骤完成插件。

```yaml
# 第一步,在apiDoc中为接口配置缓存时长信息
# x-oai-cache:
# expire: 86400
# api.yaml

/users/{userId}:
get:
tags:
- User
description: find a user by userId
x-oai-cache:
expire: 86400
x-oai-controller:
- file: people
handler: get
parameters:
- name: userId
in: path
required: true
type: number
responses:
default:
description: unexpected error
schema:
$ref: '#/definitions/Error'
```

```js
/*
* 第二步,开发x-oai-cache插件
* 获取apiDoc中x-oai-cache选项的配置信息,并返回一个koa中间件
*/
export default (config) => {
// config 内容为 {expire: 86400}
return (ctx, next) => {
// 开发你的插件业务
}
}
```

```js
/*
* 第三步,将你的业务插件挂载在路由上
*/
var router = new Router(opt);

var cachePlugin = new Cache({
store: new Redis()
});

router.use('x-oai-cache', cachePlugin);

app.use(router.routes());
app.use(router.apiExplorer());
```

## Router.extend(endpoint, fn)

Expand Down Expand Up @@ -629,7 +749,8 @@ definitions:


# 计划
* 支持OpenAPI/Swagger1.x规范
* ~~支持OpenAPI/Swagger1.x规范~~
* 支持OpenAPI/Swagger3.0规范
* 支持OpenAPI/Swagger2.0协议中的Security校验
* 支持接口的返回结果校验
* 更多的Json Schema校验引擎调研
Expand Down
1 change: 1 addition & 0 deletions example/app.js
Expand Up @@ -22,3 +22,4 @@ var router = new Router(opt);

app.use(router.routes());
app.use(router.apiExplorer());
app.use(router.apiExplorerV3());
33 changes: 33 additions & 0 deletions lib/oai-explorer-v3.js
@@ -0,0 +1,33 @@
import views from 'koa-views-swagger';
import mount from 'koa-mount';
import statics from 'koa-static';
import compose from 'koa-compose';
import path from 'path';
import Debug from 'debug';

const debug = Debug('koa-oai-router:explorer');

export default class SwaggerExplorer {
constructor(options) {
options.apiExplorerPath = `${options.apiExplorerPath}-v3`;
options.apiExplorerStaticPath = `${options.apiExplorerStaticPath}-v3`;
options.apiExplorerLink = `${options.apiExplorerLink}-v3`;

if (!options.apiExplorerVisible)
return (ctx, next) => {return next();};

debug('render api-explorer', options);
console.log(`ApiExplorer: http://127.0.0.1:${options.port}${options.apiExplorerPath}`);

return compose([
views(__dirname, {map: {html: 'mustache'}}),
mount(options.apiExplorerStaticPath, statics(path.dirname(options.apiDoc))),
mount(options.apiExplorerStaticPath, statics(`${__dirname}/../node_modules/koa-oai-router-swagger-ui-dist`)),
mount(options.apiExplorerPath, async (ctx, next) => {
options.apiDoc = path.basename(options.apiDoc);
await ctx.renderSwaggerApiExplorer('../node_modules/koa-oai-router-swagger-ui-dist/index.html', options);
})
]);
}
}

4 changes: 2 additions & 2 deletions lib/oai-explorer.js
Expand Up @@ -16,12 +16,12 @@ export default class SwaggerExplorer {
console.log(`ApiExplorer: http://127.0.0.1:${options.port}${options.apiExplorerPath}`);

return compose([
views(`${__dirname}/swagger-ui`, {map: {html: 'mustache'}}),
views(__dirname, {map: {html: 'mustache'}}),
mount(options.apiExplorerStaticPath, statics(path.dirname(options.apiDoc))),
mount(options.apiExplorerStaticPath, statics(`${__dirname}/swagger-ui`)),
mount(options.apiExplorerPath, async (ctx, next) => {
options.apiDoc = path.basename(options.apiDoc);
await ctx.renderSwaggerApiExplorer('index', options);
await ctx.renderSwaggerApiExplorer('./swagger-ui/index.html', options);
})
]);
}
Expand Down

0 comments on commit 01479d3

Please sign in to comment.