{"id":15286121,"url":"https://github.com/muniftanjim/express-joi-openapi","last_synced_at":"2025-04-13T03:07:50.254Z","repository":{"id":40754578,"uuid":"285296670","full_name":"MunifTanjim/express-joi-openapi","owner":"MunifTanjim","description":"Express + Joi + OpenAPI","archived":false,"fork":false,"pushed_at":"2022-12-11T16:40:27.000Z","size":566,"stargazers_count":6,"open_issues_count":2,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-13T03:07:42.962Z","etag":null,"topics":["express","joi","openapi","openapi-generator","openapi-specification"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/MunifTanjim.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-05T13:30:11.000Z","updated_at":"2021-07-29T15:01:22.000Z","dependencies_parsed_at":"2023-01-27T03:15:17.857Z","dependency_job_id":null,"html_url":"https://github.com/MunifTanjim/express-joi-openapi","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":"MunifTanjim/npm-package-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MunifTanjim%2Fexpress-joi-openapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MunifTanjim%2Fexpress-joi-openapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MunifTanjim%2Fexpress-joi-openapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MunifTanjim%2Fexpress-joi-openapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MunifTanjim","download_url":"https://codeload.github.com/MunifTanjim/express-joi-openapi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248657918,"owners_count":21140846,"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":["express","joi","openapi","openapi-generator","openapi-specification"],"created_at":"2024-09-30T15:10:34.360Z","updated_at":"2025-04-13T03:07:50.235Z","avatar_url":"https://github.com/MunifTanjim.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub Workflow Status: CI](https://img.shields.io/github/workflow/status/MunifTanjim/express-joi-openapi/CI?label=CI\u0026style=for-the-badge)](https://github.com/MunifTanjim/express-joi-openapi/actions?query=workflow%3ACI)\n[![Version](https://img.shields.io/npm/v/express-joi-openapi?style=for-the-badge)](https://npmjs.org/package/express-joi-openapi)\n[![Coverage](https://img.shields.io/codecov/c/gh/MunifTanjim/express-joi-openapi?style=for-the-badge)](https://codecov.io/gh/MunifTanjim/express-joi-openapi)\n[![License](https://img.shields.io/github/license/MunifTanjim/express-joi-openapi?style=for-the-badge)](https://github.com/MunifTanjim/express-joi-openapi/blob/main/LICENSE)\n\n# Express + Joi + OpenAPI\n\nExpress + Joi + OpenAPI\n\n## Installation\n\n```sh\n# using yarn:\nyarn add express-joi-openapi\n\n# using npm:\nnpm install --save express-joi-openapi\n```\n\n## Usage\n\n```ts\nimport express from 'express'\nimport {\n  ExpressOpenAPI,\n  getJoiRequestValidatorPlugin,\n  getJoiResponseValidatorPlugin,\n  RequestValidationError,\n  ResponseValidationError,\n} from 'express-joi-openapi'\nimport Joi from '@hapi/joi'\n\nconst expressOpenApi = new ExpressOpenAPI()\n\nconst requestValidatorPlugin = getJoiRequestValidatorPlugin()\nconst responseValidatorPlugin = getJoiResponseValidatorPlugin()\n\nconst validateRequest = expressOpenApi.registerPlugin(requestValidatorPlugin)\nconst validateResponse = expressOpenApi.registerPlugin(responseValidatorPlugin)\n\nconst app = express()\n\napp.use(express.json())\n\napp.post(\n  '/ping',\n  validateRequest({\n    query: {\n      count: Joi.number()\n        .integer()\n        .required()\n        .label('pong count')\n        .description('number of times ping will pong'),\n    },\n    body: {\n      type: Joi.string().valid('plastic', 'rubber', 'wood').default('rubber'),\n    },\n  }),\n  validateResponse({\n    200: {\n      body: {\n        pong: Joi.number().integer().required(),\n      },\n    },\n    default: {},\n  }),\n  (req, res) =\u003e {\n    const { count } = req.query\n\n    res.status(200).json({\n      pong: count,\n    })\n  }\n)\n\napp.use((err, _req, res, _next) =\u003e {\n  if (err instanceof RequestValidationError) {\n    res.status(400).json({\n      error: {\n        message: err.message,\n        segment: err.segment,\n        details: err.validationError.details.map(({ message, path, type }) =\u003e ({\n          message,\n          path,\n          type,\n        })),\n      },\n    })\n\n    return\n  }\n\n  if (err instanceof ResponseValidationError) {\n    console.error(err)\n\n    res.status(500).json({\n      error: {\n        message: 'Server Error: Invalid Response Schema',\n      },\n    })\n\n    return\n  }\n\n  res.status(500).json({\n    error: {\n      message: 'Server Error',\n    },\n  })\n})\n\nconst specification = expressOpenApi.populateSpecification(app)\n```\n\n## Plugin\n\nYou get the following plugins out of the box:\n\n- `JoiRequestValidatorPlugin`\n- `JoiResponseValidatorPlugin`\n\nBut that's not the end of it. You can write you own `ExpressOpenAPIPlugin` to perform arbitrary changes to\nthe OpenAPI Specification for your express routes.\n\n**Plugin Example:**\n\n```ts\nimport { Handler } from 'express'\nimport { ExpressOpenAPIPlugin } from 'express-joi-openapi'\n\ntype AuthorizationMiddleware = (permissions: string[]) =\u003e Handler\n\ntype AuthorizationPlugin = ExpressOpenAPIPlugin\u003c\n  string[],\n  AuthorizationMiddleware\n\u003e\n\nexport const getAuthorizationPlugin = (): AuthorizationPlugin =\u003e {\n  const authorizationPlugin: AuthorizationPlugin = {\n    name: 'authorization-plugin',\n\n    getMiddleware: (internals, permissions) =\u003e {\n      const middleware: Handler = async (req, res, next) =\u003e {\n        // do regular stuffs that you do in your authorization middleware\n\n        /*\n        const hasSufficientPermission = await checkUserPermission(\n          req.user,\n          permissions\n        )\n\n        if (!hasSufficientPermission) {\n          return res.status(403).json({\n            error: {\n              message: `Not Authorized`,\n            },\n          })\n        }\n        */\n\n        next()\n      }\n\n      // this will be available as a parameter to `processRoute`  function\n      internals.stash.store(middleware, permissions)\n\n      return middleware\n    },\n\n    processRoute: (specification, permissions, { path, method }) =\u003e {\n      specification.addPathItemOperationSecurityRequirement(path, method, {\n        BearerAuth: permissions,\n      })\n    },\n  }\n\n  return authorizationPlugin\n}\n```\n\n## Acknowledgement\n\nThis project draws inspiration from the following awesome projects:\n\n- [AlbertoFdzM/express-list-endpoints](https://github.com/AlbertoFdzM/express-list-endpoints)\n- [arb/celebrate](https://github.com/arb/celebrate)\n- [Twipped/joi-to-swagger](https://github.com/Twipped/joi-to-swagger)\n\n## License\n\nLicensed under the MIT License. Check the [LICENSE](./LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuniftanjim%2Fexpress-joi-openapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuniftanjim%2Fexpress-joi-openapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuniftanjim%2Fexpress-joi-openapi/lists"}