api doc and validator
npm install api-doc-validator
* @url
* @baseUrl
* @params
* @query
* @body
* @response
* @namespace
* @schema
* @call
* METHOD
* CODE
* path
* OBJECT_NAME
* json-schema
* object-method-call
* cli
* API client
* Express middleware
* Universal middleware
* Swagger OpenAPI
* Validation errors handling
* Config
```
@url [METHOD] path
`javascript`
/**
* Some description
* @url POST /path/:param
*/
``
@baseurl path
`javascript
/**
* @baseUrl /v1
*/
/**
* @url /users
*/
`
Final url will be /v1/users
Validate parameters of @url path
``
@params [OBJECT_NAME =] json-schema|OBJECT_NAME
`javascriptid
/**
* @url GET /users/:id
* @params {
* # some description for (usefull for OpenApi)`
* id: number,
* }
* @call users.get(id)
*/OBJECT_NAME
or with assign for future use`javascriptid
/**
* @url GET /users/:id
* @params User = {
* id: number, // description for `
* }
*/`
or use an external schema as root schemajavascript`
/**
* @url GET /users/:id
* @params User
*/`
or extend external schemajavascript`
/**
* @url GET /users/:id
* @params {
* ...User,
* name: string,
* }
*/
Validate @url query parameters
``
@query [OBJECT_NAME =] json-schema|OBJECT_NAME
`javascript`
/**
* @url GET /users
* @query {
* id: number,
* }
* @call users.get(id)
*/GET /users?id=1
Example of valid request
Names of fields in @params and query should be different to use them in @call`javascript`
/**
* @url GET /users/:id
* @params {
* id: number,
* }
* @query {
* name: string,
* }
* @call users.get(id, name)
*/
``
@body [# Description] [OBJECT_NAME =] json-schema|OBJECT_NAME
`javascript
/**
* @body {
* id: number,
* name: string,
* }
* @body User = {
* id: number,
* name: string,
* }
* @body
* # Some body description
* User = {
* id: number,
* name: string,
* }
*/
`
Response http code and validation of response body.
``
@response [CODE] [# Description] [OBJECT_NAME =] json-schema|OBJECT_NAME200
Response for code`javascript`
/**
* @response {
* id: number,
* name: string,
* }
*/`
Validators for different codes of same requestjavascript`
/**
* @response 200 {
* id: number,
* name: string,
* }
* @response 500
* # Some description
* {
* message: string,
* }
*/
Shortcut @ns
Word used to filter validators in target file.
`js
/**
* Namespace for this validator will be "default"
*
* @url POST /users
* @body {id: number}
*/
/**
* @namespace test
* @url POST /test-success
* @response 2xx {success: boolean}
*/
/**
* @ns test
* @url POST /test-error
* @response 5xx {error: boolean}
*/
`test
Example of generation express middleware with only validators``
npx adv -c path/to/config.json -n test -e ./test-validator.js
Define the new schema for future usage
``
@schema OBJECT_NAME = json-schema|OBJECT_NAME
`javascript`
/**
* @schema User = {
* id: number,
* name: string,
* }
*/`
or just to make shorter schema namejavascript`
/**
* @schema User = SomeVeryLongSchemaName
*/
You should provide valid js code of method call. This code will be used in your API tests.
``
@call object-method-call
`javascript`
/**
* @call object.method(param1, param2)
*/
HTTP request method. Default is config.defaultMethod
``
GET|POST|PUT|DELETE|HEAD|OPTIONS
HTTP response code. Default is config.defaultCode
Formats:
* 200 regular code number2xx
* any code between 200 and 299200 - 400
* any code between 200 and 400200 || 3xx || 400 - 500
* or expression `
Examplejavascript`
/**
* @response 2xx || 301 User = {id: number}
*/
URL pathname. For path parsing used path-to-regexp lib.
Parameters like :id can be used in @call as parameter of method call with same name.
`javascript`
/**
* @url GET /users/:id(\d+)
* @call users.get(id)
*/
Any valid js object name like objectName or with field of any deep objectName.fieldName.field
Object that describes how validate another object. For validation used ajv.
For syntax details see adv-parser
Uniq sample of JavaScript code with some method call of some object, which will be generated for testing purposes.
In method call you can use named parameters from @url`javascript
/**
* @url GET /users
* @call users.get()
*/
/**
* @url GET /users/:id
* @call users.get(id)
*/
/**
* @url POST /users/:id/settings
* @call users.setSettings(id)
*/
/**
* @url POST /users/:id/settings
* @call users.settings.update(id)
*/
`
There can be any number of nested objects and any method name. Only names of parameters should be equal.
with npx
npx adv -c path/to/config.json
Parameters:
`
-c, --config
-i, --include
-a, --api-client
-d, --api-dts
-b, --base-url
-p, --base-path
-e, --express
-o, --open-api
-j, --json
-s, --only-schemas [names...] save schemas instead of endpoints to json file
-n, --namespace
-M, --default-method
-C, --default-code default @response CODE`
-S, --default-schemas
-J, --jsdoc-methods
-T, --jsdoc-typedefs
-R, --jsdoc-refs
-I, --include-jsdoc
-P, --extra-props
-N, --class-name
--path-to-regexp
--request-method
--get-ajv-method
--error-handler-method
Install in to your project packages ajv, ajv-formats (optional if you not using String patterns), request (if you don't like request then you will need to implement Api.request) and path-to-regexp. Client will depend on them.
Generate the API client with npx adv -c path/to/config.json -a path/to/your/app/api-client.js
Example
`js
/**
* @url POST /users
* @body User = {id: number, name: string}
* @response 200 User
* @call addUser()
*/
/**
* @url GET /users/:id
* @params {id: number}
* @response 200 User
* @call users.get()
*/
`api-client.js
Generated will export class Api.`js
const Api = require('./path/to/your/app/api-client.js');
const client = new Api(/ "https://new.base.url" optionaly, default is Api.baseUrl /);
console.log(Api.baseUrl); // value from config.baseUrl or --base-url cli option
console.log(Api.endpoints); // parsed endpoints from comments
// optionaly
Api.getAjv = () => createYourAjvInstance();
Api.request = function ({
method,
url,
params / url params like /:id /,
query,
body,
endpoint / object from Api.endpoints /,
context / Api class instance /
}) {
return sendRequestReturnPromise(context.baseUrl + url);
}
Api.errorHandler = function (err) {
console.error(err);
throw err;
};
// --
await client.addUser({id: 1, name: 'Test'});
client.users.get({id: 1} / or just 1 if @params has only one parameter /)
.then(user => {
console.log(user.name);
console.log(client.requestCookieJar); // @see request.jar() https://github.com/request/request#examples
})
.catch(err => {
// @see Validation errors handling
});
`
Install in to your project packages ajv, ajv-formats (optional if you not using String patterns) and path-to-regexp. Middleware depends on them.
Generate the middleware with npx adv -c path/to/config.json -e path/to/your/app/validator.js
Then add middleware to your express app
`js
const validator = require('./path/to/your/app/validator.js');
// optionaly
validator.getAjv = () => createYourAjvInstance();
// --
app.use(validator);
app.post('...', (req, res) => {});
app.use(function (err, req, res, next) {
if (err instanceof validator.RequestValidationError) {
// @see Validation errors handling
}
else if (err instanceof validator.ResponseValidationError) {
// @see Validation errors handling
}
else {
next(err);
}
// or use base class
if (err instanceof validator.ValidationError) {
// @see Validation errors handling
}
else {
next(err);
}
});
`
Generate the middleware with npx adv -c path/to/config.json -e path/to/your/app/validator.js
Then add it to your app
`js
const validator = require('./validator.js');
function sendMessage(path, data) {
try {
var validateResponse = validator({
url: path,
body: data,
});
}
catch (err) {
// @see RequestValidationError
}
return ajax(path, data).then(function (result) {
if (validateResponse) {
try {
validateResponse(result);
}
catch (err) {
// @see ResponseValidationError
}
}
return result;
});
}
`
Generate Swagger OpenAPI v3 json with npx adv -c path/to/config.json -o path/to/open-api.json
Both Api class and middleware exports three classes:
* ValidationError - base class, extends ErrorRequestValidationError
* - class of request validation error, extends ValidationError ResponseValidationError
* - class of response validation error, extends ValidationError
`js
let err; // error from api client or middleware validator
let context; // Api class or middleware
if (err instanceof context.RequestValidationError) {
console.log(err.message);
console.log(err.property); // query | params | body
console.log(err.errors); // @see https://github.com/ajv-validator/ajv/blob/master/docs/api.md#validation-errors
}
else if (err instanceof context.ResponseValidationError) {
console.log(err.message); // "Invalid response body"
console.log(err.errors); // @see https://github.com/ajv-validator/ajv/blob/master/docs/api.md#validation-errors
}
// or use base class
if (err instanceof context.ValidationError) {
console.log(err.message);
console.log(err.property);
console.log(err.errors);
}
`
* include array of paths to files relative to config path, glob pattern usedexclude
* array of paths to files to be excludeddefaultMethod
* overwrites default METHOD. Default is GETdefaultCode
* overwrites default CODE. Default is 200defaultSchemas
* same as --default-schemas jsdocMethods
* generate @type for each method. Default is truejsdocTypedefs
* generate @typedef for each named schema. Default is truejsdocRefs
* use references to @typedef or replace them with reference body. Default is trueapiClient
* same as --api-client apiDts
* same as --api-dts basePath
* same as --base-path json
* same as --json onlySchemas
* array of schemas names to be saved as json. Could be true or empty array then will be exported all schemas. json
If no parameter passed then formatted json will output to consoleexpress
* same as --express openApi
* same as --open-api namespace
* same as --namespace includeJsdoc
* same as --include-jsdoc extraProps
* same as --extra-props
All paths are relative to config file location.
Example
`json``
{
"include": [
"src/*/.js",
"src/*/.php"
],
"exclude": [
"src/tests"
],
"defaultMethod": "POST",
"defaultCode": "2xx || 301"
}