{"id":13800296,"url":"https://github.com/zaaack/koa-joi-swagger","last_synced_at":"2025-07-06T08:35:00.924Z","repository":{"id":74324792,"uuid":"89457546","full_name":"zaaack/koa-joi-swagger","owner":"zaaack","description":"An opinionated koa validation \u0026 swagger library, letting you write one Joi schema for both validation \u0026 generating swagger ui.","archived":false,"fork":false,"pushed_at":"2018-08-13T08:41:39.000Z","size":129,"stargazers_count":75,"open_issues_count":3,"forks_count":11,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-04-30T15:10:18.465Z","etag":null,"topics":["joi","joi-to-json-schema","koa","swagger","swagger-ui","validation"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zaaack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-04-26T08:31:47.000Z","updated_at":"2023-11-15T02:23:04.000Z","dependencies_parsed_at":"2024-01-12T09:46:09.848Z","dependency_job_id":null,"html_url":"https://github.com/zaaack/koa-joi-swagger","commit_stats":{"total_commits":17,"total_committers":2,"mean_commits":8.5,"dds":"0.17647058823529416","last_synced_commit":"72820f8f1ecdf4ac787f0423c13ff92a8c68ff5d"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaaack%2Fkoa-joi-swagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaaack%2Fkoa-joi-swagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaaack%2Fkoa-joi-swagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zaaack%2Fkoa-joi-swagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zaaack","download_url":"https://codeload.github.com/zaaack/koa-joi-swagger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249797680,"owners_count":21326845,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["joi","joi-to-json-schema","koa","swagger","swagger-ui","validation"],"created_at":"2024-08-04T00:01:11.200Z","updated_at":"2025-04-23T14:25:59.358Z","avatar_url":"https://github.com/zaaack.png","language":"JavaScript","funding_links":[],"categories":["仓库"],"sub_categories":["中间件"],"readme":"# koa-joi-swagger\n\n* Using joi schema to validate request \u0026 response, and generate swagger document to create beautiful API documents.\n\n\n[![Build Status](https://travis-ci.org/zaaack/koa-joi-swagger.svg?branch=master)](https://travis-ci.org/zaaack/koa-joi-swagger) [![npm](https://img.shields.io/npm/v/koa-joi-swagger.svg)](https://www.npmjs.com/package/koa-joi-swagger) [![npm](https://img.shields.io/npm/dm/koa-joi-swagger.svg)](https://www.npmjs.com/package/koa-joi-swagger)\n\n## Feature\n\n* Router agnostic.\n* Using your favorite library for validation, and generate swagger document for develop.\n* Serving Swagger UI in your koa project.\n* ...\n\n## Install\n\n```sh\nnpm i koa-joi-swagger\n\n```\n\nor\n\n```sh\nyarn add koa-joi-swagger\n```\n\nfor v3, install optional dependencies\n```sh\nnpm i swagger-ui-dist # or yarn add swagger-ui-dist\n```\n\n\n## Example\n\n```sh\ngit clone https://github.com/zaaack/koa-joi-swagger.git\ncd koa-joi-swagger\nyarn # or npm i\nSERVE=1 npx babel-node ./test/fixtures/server.js\n```\n\nNow open \u003chttp://127.0.0.1:3456/swagger\u003e!\n\n## Demo\n\napp.js\n```js\nimport { toSwaggerDoc, ui, mixedValidate } from '../../src'\nimport mixedDoc from './mixed-doc'\nimport Koa from 'koa'\nimport DecRouter from 'koa-dec-router'\nimport bodyparser from 'koa-bodyparser'\n\nconst app = new Koa()\n\nconst decRouter = DecRouter({\n  controllersDir: `${__dirname}/controllers`,\n})\n\napp.use(bodyparser())\n\nconst swaggerDoc = toSwaggerDoc(mixedDoc)\n// mount swagger ui in `/swagger`\napp.use(ui(swaggerDoc, {pathRoot: '/swagger'}))\n\n// handle validation errors\napp.use(async (ctx, next) =\u003e {\n  try {\n    await next()\n  } catch (e) {\n    if (e.name === 'RequestValidationError') {\n      ctx.status = 400\n      ctx.body = {\n        code: 1,\n        message: e.message,\n        data: e.data,\n      }\n    } else if (e.name === 'ResponseValidationError') {\n      ctx.status = 500\n      ctx.body = {\n        code: 1,\n        message: e.message,\n        data: e.data,\n      }\n    }\n  }\n})\n\n// validate request and response by mixedDoc\napp.use(mixedValidate(mixedDoc, {\n  onError: e =\u003e console.log(e.details, e._object),\n}))\n\n// koa-dec-router\napp.use(decRouter.router.routes())\napp.use(decRouter.router.allowedMethods())\n\napp.listen(3456)\n```\n\n\u003e \"I see the api is simple, but how to write the joi schema and the swagger document?\"\n\nThat's the point, you don't need to write a joi schema to validation and a swagger document to create API documents.\n\n\u003e \"Oh, no, Should I learn a new schema?\"\n\nOf 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.\n\nTherefore, to make this library simple and reliable, I just mixed joi and swagger document, and using [joi-to-json-schema](https://github.com/lightsofapollo/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.\n\nI call it mixed document, here is an example.\n\n```js\nexport default {\n  swagger: '2.0',\n  info: {\n    title: 'Test API',\n    description: 'Test API',\n    version: '1.0.0',\n  },\n  //  the domain of the service\n  //  host: 127.0.0.1:3457\n  //  array of all schemes that your API supports\n  schemes: ['https', 'http'],\n  //  will be prefixed to all paths\n  basePath: '/api/v1',\n  consumes: ['application/x-www-form-urlencoded'],\n  produces: ['application/json'],\n  paths: {\n    '/posts': {\n      get: {\n        summary: 'Some posts',\n        tags: ['Post'],\n        parameters: {\n          query: Joi.object().keys({\n            type: Joi.string().valid(['news', 'article']),\n          }),\n        },\n        responses: {\n          '200': {\n            x: 'Post list',\n            schema: Joi.object().keys({\n              lists: Joi.array().items(Joi.object().keys({\n                title: Joi.string().description('Post title'),\n                content: Joi.string().required().description('Post content'),\n              }))\n            }),\n          },\n          'default': {\n            description: 'Error happened',\n            schema: Joi.object().json().keys({\n              code: Joi.number().integer(),\n              message: Joi.string(),\n              data: Joi.object(),\n            }),\n          },\n        }\n      }\n    },\n  },\n}\n```\n\nYou can see the differences between this and the real swagger document, just replace `parameters` and `responses` to joi schema instead of JSON schema,\n\n[Here is the swagger document that generate from mixed document above](docs/swagger-doc-from-mixed-doc.json).\n\n## API\n\n```js\nimport JoiSwagger, {\n  toSwaggerDoc, mixedValidate, joiValidate, ui\n} from 'koa-joi-swagger'\nimport Koa from 'koa'\n\nconst app = new Koa()\n/*\n\nJoiSwagger = {\n  toSwaggerDoc,\n  mixedValidate,\n  joiValidate,\n  ui,\n  Joi,\n}\n */\n\nconst mixedDoc = require('./mixed-doc')\n\nconst swaggerDoc = toSwaggerDoc(mixedDoc) // parse mixed document to swagger document for swagger-ui\n\n\n//\n// const defaultResJoiOpts = {\n//   stripUnknown: true,\n//   convert: true,\n// }\napp.use(mixedValidate(mixedDoc, {\n  reqOpts: {\n    stripUnknown: false,\n    convert: true,\n  }, // optional, ctx.request joi validation options, here is default\n  resOpts: { // optional, ctx.response joi validation options, here is default\n    stripUnknown: true, // this would remove additional properties\n    convert: true, // this would convert field types\n  },\n  onError: err =\u003e console.error(err), // Do something with the error, the error would throw anyway.\n}))\n\napp.use(ui(swaggerDoc, {\n  pathRoot: '/swagger', // optional, swagger path\n  skipPaths: [], // optional, skip paths\n  UIHtml: defaultUIHtml, // optional, get ui html\n  swaggerConfig: '', // optional, a json5 string, e.g. `{ \u003cfield\u003e: \u003cvalue\u003e, .... }` to display in html for overriding swagger ui options.\n  sendConfig: { maxage: 3600 * 1000 * 24 * 30 }, // optional, config for koa-send, default maxage is 1 month.\n  v3: false, // optional, default is v2, you need to install optional dependencies `swagger-ui-dist` first.\n\n}))\n\n// joiValidate // the internal joi validation function used by mixedValidate, in case you need one.\n// JoiSwagger.Joi // The joi used to validate, with some opinionated extension, you can override it or using it.\n\n```\n\n## Q \u0026 A\n\n#### 1. Why not using [ajv](https://github.com/epoberezkin/ajv) to validate by swagger document directly?\n\nI 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.\n\n#### 2. Why not using YAML?\n\nYAML 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.\n\n#### 3. You extended Joi, why?\n\nSorry, 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.\n\nAlso, 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.\n\n\nAdded 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).\n\n[See the code](src/joi.js)\n\nAnd I highly recommend using this extended joi to write your schemas, and adding your extension if you need.\n\nYou can also using other version of Joi to validate.\n\n```js\nimport JoiSwagger from 'koa-joi-swagger'\nimport myJoi from './myJoi'\n\n// using\nexport const Joi = JoiSwagger.Joi\n\n// override\nJoiSwagger.Joi = myJoi\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaaack%2Fkoa-joi-swagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzaaack%2Fkoa-joi-swagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzaaack%2Fkoa-joi-swagger/lists"}