@novice1/api-doc-generator
v0.2.6
Published
Quickly generate API Documentation.
Downloads
99
Readme
@novice1/api-doc-generator
Generate API documentation directly from application.
Installation
$ npm install @novice1/api-doc-generator
OpenAPI Specification
Default
By default it handles joi
schemas.
Example:
import {
GenerateComponentsRule,
OpenAPI
} from '@novice1/api-doc-generator';
import routing from '@novice1/routing';
import Joi from 'joi';
const openapi = new OpenAPI();
openapi
.setTitle('api doc')
.setHost('http://localhost:8000')
.setConsumes(['application/json'])
.setTags([
{
name: 'default',
externalDocs: { description: 'Find more info here', url: 'https://swagger.io/specification/' }
}
])
.setGenerateComponentsRule(GenerateComponentsRule.ifUndefined)
.setResponsesProperty('openapi')
.setSecuritySchemes({
basicAuth: {
type: 'http',
scheme: 'basic',
}
})
.setDefaultSecurity([
{
basicAuth: []
}
]);
const router = routing()
.get({
name: 'Main app',
path: '/app',
auth: true,
tags: ['default'],
parameters: {
query: {
version: Joi.number()
.description('version number')
.min(1)
.max(3)
.default(2)
.example(2)
},
operationId: 'default-app',
undoc: false, // set to `true` to not display the route in the documentation
// override consumes
consumes: ['application/json'],
// override default security
security: ['basicAuth'],
},
responses: {
openapi: {
default: {
description: 'Version number',
content: {
'application/json': {
schema: {
type: 'number',
example: 2
}
}
}
}
}
}
}, function (req, res) {
res.json(req.query.version)
});
// add router metadata
openapi.add(router.getMeta());
// get OpenAPI Object (json)
const doc = openapi.result();
Postman Specification
Postman Collection Format v2.1.0.
Default
By default it handles joi
schemas.
Example:
import {
GenerateFoldersRule,
Postman
} from '@novice1/api-doc-generator';
import routing from '@novice1/routing';
import Joi from 'joi';
const postman = new Postman();
postman
.setName('api doc')
.setHost('http://localhost:8000')
.setConsumes(['multipart/form-data', 'application/json'])
.setFolders([
{
name: 'default',
description: 'A folder is just an ordered set of requests.',
item: [],
}
])
.setGenerateFoldersRule(GenerateFoldersRule.siblings)
.setResponsesProperty('postman')
.setDefaultSecurity({
type: 'basic',
basic: []
});
const router = routing()
.get({
name: 'Main app',
path: '/app',
auth: true,
tags: ['default'], // folders
parameters: {
query: {
version: Joi.number()
.description('version number')
.min(1)
.max(3)
.default(2)
.example(2)
},
operationId: 'default-app',
// override consumes
consumes: ['application/json'],
// override default security
security: ['basic'],
},
responses: {
postman: {
// ...
}
}
}, function (req, res) {
res.json(req.query.version)
});
// add router metadata
postman.add(router.getMeta());
// get Postman Collection (json)
const doc = postman.result();
Schema helpers
Default helper
Types
The default helper handles the following joi
types: alternatives
, any
, array
, boolean
, date
function
, number
, object
, string
, binary
.
It also handles format methods like Joi.string().email()
, Joi.string().url()
and more.
In some cases you might have to precise the format in Joi.meta
. For example Joi.string().meta({format: 'password'})
, Joi.date().meta({format: 'datetime'})
or more.
Handled formats are:
boolean
object
array
number
string
date
date-time
datetime
float
double
integer
int32
int64
byte
binary
password
email
guid
uuid
uri
dataUri
Joi.meta
You can configure multiple elements in Joi.meta
like a reference to a component. For example:
Joi.object()
.keys({
name: Joi.string().required(),
petType: Joi.string().required()
})
.meta({ ref: '#/components/schemas/Pet' })
If the reference is local (#
), it could automatically generate the component depending on the rule you set (see OpenAPI.setGenerateComponentsRule
).
List of elements you can configure in Joi.meta
:
additionalProperties
allowReserved
deprecated
discriminator
examples
explode
encoding
format
ref
style
xml
The possible value for each of them is defined in the OpenAPI Specification.
Custom helper
You can create your own helper to handle another schema than joi
.
The helper
- needs to be a class that implements
OpenAPIHelperInterface
(forOpenAPI
)- or
PostmanHelperInterface
(forPostman
)
- should be given to the generator's constructor.
Example:
import { OpenAPI, Postman } from '@novice1/api-doc-generator';
import {
CustomOpenAPIHelperClass,
CustomPostmanHelperClass
} from './custom';
const openapi = new OpenAPI(CustomOpenAPIHelperClass);
const postman = new Postman(CustomPostmanHelperClass);
Utils
As the format differs between specifications, some classes can help you generate the documentation following multiple specifications.
Auth
Classes:
Example:
import {
OpenAPI,
Postman,
BearerUtil
} from '@novice1/api-doc-generator';
import routing from '@novice1/routing';
// security scheme
const bearerAuth = new BearerUtil('bearerName');
// add it to OpenAPI security schemes
const openapi = new OpenAPI();
openapi.addSecuritySchemes(bearerAuth);
// add it to Postman global authentication
const postman = new Postman();
postman.setAuth(bearerAuth);
// router
const router = routing()
.get({
path: '/something',
auth: true,
parameters: {
// add security requirements for this route
security: bearerAuth
}
}, function (req, res) {
// ...
});
Context
You can wrap the instance with a context to define a scope
depending on the route. You do that with ContextAuthUtil
.
Example:
import routing from '@novice1/routing';
import {
OpenAPI,
Postman,
ContextAuthUtil,
OAuth2Util,
GrantType
} from '@novice1/api-doc-generator';
// OAuth2 specifications
const oauth2 = new OAuth2Util('oAuth2AuthCode');
oauth2
.setDescription('For more information, see https://api.slack.com/docs/oauth')
.setGrantType(GrantType.authorizationCode)
.setAuthUrl('https://slack.com/oauth/authorize')
.setAccessTokenUrl('https://slack.com/api/oauth.access')
.setScopes({
'users:read': 'Read user information',
'users:write': 'Modify user information',
'im:read': 'Read messages',
'im:write': 'Write messages',
'im:history': 'Access the message archive',
'search:read': 'Search messages, files, and so on'
});
// add it to OpenAPI security schemes
const openapi = new OpenAPI();
openapi.addSecuritySchemes(oauth2);
// add it to Postman global authentication
const postman = new Postman();
postman.setAuth(oauth2);
// router
const router = routing()
.get({
path: '/messages',
auth: true,
parameters: {
// add security requirements for this route
security: new ContextAuthUtil(
oauth2,
// OAuth2 scopes for this route
['im:read']
)
}
}, function (req, res) {
// ...
});
Group
You can group security schemes at your convenience with GroupAuthUtil
and GroupContextAuthUtil
.
Exemple:
import {
OpenAPI,
Postman,
BasicAuthUtil,
BearerUtil,
GroupAuthUtil,
GroupContextAuthUtil
} from '@novice1/api-doc-generator';
const basicAuth = new BasicAuthUtil('basicAuthName');
const bearerAuth = new BearerUtil('bearerName');
const groupAuth = new GroupAuthUtil([
basicAuth,
bearerAuth
]);
// add it to OpenAPI security schemes
const openapi = new OpenAPI();
openapi.addSecuritySchemes(groupAuth);
// add it to Postman global authentication
const postman = new Postman();
postman.setAuth(groupAuth);
const router = routing()
.get({
path: '/something',
auth: true,
parameters: {
// add security requirements for this route
security: new GroupContextAuthUtil([
basicAuth,
bearerAuth,
])
}
}, function (req, res) {
// ...
});
Responses
Classes:
Example:
import {
ResponseUtil,
GroupResponseUtil
} from '@novice1/api-doc-generator';
const generalError = new ResponseUtil('GeneralError');
generalError
.setDescription('General Error')
.addMediaType('application/json', {
schema: {
$ref: '#/components/schemas/GeneralError'
}
})
.setCode(500);
const illegalInput = new ResponseUtil('IllegalInput');
illegalInput
.setDescription('Illegal input for operation.')
.setCode(400);
const responses = new GroupResponseUtil([
generalError,
illegalInput
]);
openapi.setResponses(responses);
// or
openapi.addResponse(responses);
// or
openapi
.addResponse(generalError)
.addResponse(illegalInput);
// router
const router = routing()
.post({
path: '/something',
auth: true,
parameters: {
body: {
something: Joi.string().max(14)
},
responses
}
}, function (req, res) {
// ...
});
Context
You can wrap the instance with a context if you want to define default
, code
, ref
and/or links
depending on the route. You do that with ContextResponseUtil
.
Example:
const generalError = new ResponseUtil('GeneralError');
generalError
.setDescription('General Error')
.addMediaType('application/json', {
schema: {
$ref: '#/components/schemas/GeneralError'
}
});
const illegalInput = new ResponseUtil('IllegalInput');
illegalInput
.setDescription('Illegal input for operation.');
// router
const router = routing()
.get({
path: '/something',
auth: true,
parameters: {
responses: new GroupResponseUtil([
(new ContextResponseUtil(generalError))
.setCode(500).setDefault(),
(new ContextResponseUtil(illegalInput))
.setCode(400)
])
}
}, function (req, res) {
// ...
});