bews-koa-joi-swagger
- Using joi schema to validate request & response, and generate swagger document to create beautiful API documents.
Feature
- Router agnostic.
- Using your favorite library for validation, and generate swagger document for develop.
- Serving Swagger UI in your koa project.
- ...
Install
npm i bews-koa-joi-swagger
or
yarn add bews-koa-joi-swagger
for v3, install optional dependencies
npm i swagger-ui-dist # or yarn add swagger-ui-dist
Example
git clone https://github.com/zaaack/koa-joi-swagger.gitcd koa-joi-swaggeryarn # or npm i SERVE=1 babel-node ./test/fixtures/server.js
Now open http://127.0.0.1:3456/swagger!
Demo
app.js
const app = const decRouter = app const swaggerDoc = // mount swagger ui in `/swagger`app // handle validation errorsapp // validate request and response by mixedDocapp // koa-dec-routerappapp app
"I see the api is simple, but how to write the joi schema and the swagger document?"
That's the point, you don't need to write a joi schema to validation and a swagger document to create API documents.
"Oh, no, Should I learn a new schema?"
Of cause not, I hate new schemas, too, especially those made by someone or some company without long support, it's just a waste of time and my brain cell.
Therefore, to make this library simple and reliable, I just mixed joi and swagger document, and using joi-to-json-schema to transform joi schema to swagger schema. You don't have to learn a new schema, just replace the JSON schema in your swagger document to joi schema, then let this library to do the rest.
I call it mixed document, here is an example.
swagger: '2.0' info: title: 'Test API' description: 'Test API' version: '1.0.0' // the domain of the service // host: 127.0.0.1:3457 // array of all schemes that your API supports schemes: 'https' 'http' // will be prefixed to all paths basePath: '/api/v1' consumes: 'application/x-www-form-urlencoded' produces: 'application/json' paths: '/posts': get: summary: 'Some posts' tags: 'Post' parameters: query: Joiobject responses: '200': x: 'Post list' schema: Joiobject 'default': description: 'Error happened' schema: Joiobject
You can see the differences between this and the real swagger document, just replace parameters
and responses
to joi schema instead of JSON schema,
Here is the swagger document that generate from mixed document above.
API
const app = /* JoiSwagger = { toSwaggerDoc, mixedValidate, joiValidate, ui, Joi,} */ const mixedDoc = const swaggerDoc = // parse mixed document to swagger document for swagger-ui //// const defaultResJoiOpts = {// stripUnknown: true,// convert: true,// }app app // joiValidate // the internal joi validation function used by mixedValidate, in case you need one.// JoiSwagger.Joi // The joi used to validate, with some opinionated extension, you can override it or using it.
Q & A
ajv to validate by swagger document directly?
1. Why not usingI have think it before, but hit some problems like validating javascript date object, remove additionalProperties, etc. And writing JSON schema is too verbose. Joi is the best validation library in NodeJS, we should take the advantage.
2. Why not using YAML?
YAML is not easy to reuse, although JSON schema can reuse model, and how to reuse shared properties between models? I can't find a way. Pure javascrip can easily reuse or wrap model schema, and you can wrap each final schema with a function, don't feel pain when adding properties for each request schema in the future.
3. You extended Joi, why?
Sorry, joi's philosophy is too strict for me, I really don't need to explicit declare the string could be empty, so I override the original Joi.string()
to make Joi.string().empty('')
is a default behavior.
Also, add a .force()
method for string/number type, to coerce the field to string/number regardless of the original type, it's really useful when validating some bson type like Long, Deciaml or Custom object.
Added a Joi.object().json()
to coerce object with toJSON
method to a plain JSON object. This would useful when validation some ORM/ODM's model object (like mongorito).
And I highly recommend using this extended joi to write your schemas, and adding your extension if you need.
You can also using other version of Joi to validate.
// usingconst Joi = JoiSwaggerJoi // overrideJoiSwaggerJoi = myJoi