{"id":28200981,"url":"https://github.com/payu/api-contract-validator","last_synced_at":"2025-06-12T18:32:24.640Z","repository":{"id":34301806,"uuid":"174300595","full_name":"PayU/api-contract-validator","owner":"PayU","description":"Plugin for validating API response schemas against Swagger/OpenAPI definition","archived":false,"fork":false,"pushed_at":"2024-09-06T09:35:22.000Z","size":1489,"stargazers_count":31,"open_issues_count":43,"forks_count":10,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-05-16T22:14:06.725Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PayU.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-07T08:12:23.000Z","updated_at":"2024-10-04T21:26:26.000Z","dependencies_parsed_at":"2024-06-18T16:49:29.714Z","dependency_job_id":"04c1bdd3-93de-4558-aeea-62f3f10b1b1f","html_url":"https://github.com/PayU/api-contract-validator","commit_stats":{"total_commits":152,"total_committers":15,"mean_commits":"10.133333333333333","dds":0.381578947368421,"last_synced_commit":"2c8b3aefdee3fe590e87c6dca804b9950e8b1a4a"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/PayU/api-contract-validator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PayU%2Fapi-contract-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PayU%2Fapi-contract-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PayU%2Fapi-contract-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PayU%2Fapi-contract-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PayU","download_url":"https://codeload.github.com/PayU/api-contract-validator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PayU%2Fapi-contract-validator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259519255,"owners_count":22870327,"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":[],"created_at":"2025-05-16T22:14:47.531Z","updated_at":"2025-06-12T18:32:24.614Z","avatar_url":"https://github.com/PayU.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm](https://img.shields.io/npm/v/api-contract-validator.svg)](https://www.npmjs.com/package/api-contract-validator)\n[![npm](https://img.shields.io/npm/dm/api-contract-validator)](https://www.npmjs.com/package/api-contract-validator)\n[![Build Status](https://travis-ci.com/PayU/api-contract-validator.svg?branch=master)](https://travis-ci.com/PayU/api-contract-validator)\n[![Coverage Status](https://coveralls.io/repos/github/PayU/api-contract-validator/badge.svg?branch=master)](https://coveralls.io/github/PayU/api-contract-validator?branch=master)\n[![Known Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/PayU/api-contract-validator.svg)](https://snyk.io/test/github/PayU/api-contract-validator?targetFile=package.json)\n![style](https://img.shields.io/badge/code%20style-airbnb-ff5a5f.svg)\n![NPM](https://img.shields.io/npm/l/api-contract-validator.svg)\n\u003c!-- [![npm](https://img.shields.io/npm/dm/api-contract-validator.svg)](https://www.npmjs.com/package/api-contract-validator) --\u003e\n\n# api-contract-validator\nThis plugin for assertion libraries is for validating API response schemas against Swagger/OpenAPI definition. \n\nUsing the plugin is easy. Simply point the plugin to your API definitions file path and add one line to your integration test to validate that your application adheres to its design contract. \n\n## Highlights \n- Asserts according to API definitions document\n- Descriptive assertion failures\n- Simple and concise usage\n- Coverage report (can be printed to your terminal or exported to a json file)\n- Supports response format from `axios`, `superagent`, `supertest`, `request` and `light-my-request` (used by `fastify`)\n- Supports OpenAPI 3.0\n- Supports multiple definition files\n  \n\n## How does it work?\nThe api-contract-validator transforms your API definition into a json-schema based on the provided API documentation file. Then whenever the `matchApiSchema` assertion is called, it automatically extracts the method, path and status code from the response object returned by the API request that you invoked and validates the response object. Both the response headers and body are validated.\n\n## How to use?\n***Installation***\n```bash\n\u003e npm i --save-dev api-contract-validator\n```\n\n### ***Chai.js***\n```js\nconst matchApiSchema = require('api-contract-validator').chaiPlugin;\nconst path = require('path');\nconst { expect, use } = require('chai');\n\n// API definitions path\nconst apiDefinitionsPath = path.join(__dirname, 'myApp.yaml'); \n\n// add as chai plugin\nuse(matchApiSchema({ apiDefinitionsPath }));\n\nit('GET /pets/123', async () =\u003e {\n    const response = await request.get('/pet/123');\n    expect(response).to.have.status(200).and.to.matchApiSchema();\n\n    // alternatively pass\n    const { statusCode, headers, body } = response\n    expect({\n        path: '/pet/123',\n        method: 'get',\n        status: statusCode,\n        body: body,\n        headers: headers,\n    }).to.have.status(200).and.to.matchApiSchema();\n})\n```\n\n### ***Should.js***\n```js\nconst matchApiSchema = require('api-contract-validator').shouldPlugin;\n\n// API definitions path\nconst apiDefinitionsPath = path.join(__dirname, 'myApp.yaml');\n\n// add as should plugin\nmatchApiSchema(should, { apiDefinitionsPath });\n\nit('GET /pets/123', async () =\u003e {\n    const response = await request.get('/pet/123');\n    should(response).have.status(200).and.matchApiSchema();\n})\n```\n\n### ***Jest***\n```js\nconst matchApiSchema = require('api-contract-validator').jestPlugin;\n\n// API definitions path\nconst apiDefinitionsPath = path.join(__dirname, 'myApp.yaml');\n\n// add as jest plugin\nmatchApiSchema({ apiDefinitionsPath });\n\nit('GET /pets/123', async () =\u003e {\n    const response = await request.get('/pet/123');\n    expect(response).toHaveStatus(200);\n    expect(response).toMatchApiSchema();\n})\n```\n## ***Multiple api definitions files***\nuse apiDefinitionsPath option with an array of files paths\n```js\nconst apiDefinitionsPath = [path.join(__dirname, 'myApp.yaml'), path.join(__dirname, 'myApp2.yaml')];\n```\n\n## Descriptive assertion failures\n```js\nAssertionError: expected response to match API schema\n+ expected - actual\n\n{\n    \"body\": {\n-    \"age\": -1\n+    \"age\": \"should be \u003e= 0\"\n+    \"name\": \"should have required property\"\n    }\n    \"headers\": {\n-    \"x-expires-after\": []\n-    \"x-rate-limit\": -5\n+    \"x-expires-after\": \"should be string\"\n+    \"x-rate-limit\": \"should be \u003e= 0\"\n    }\n}\n```\n\n## Coverage report\nBy providing in the plugin options, the flag `reportCoverage:true`, the plugin generates a report of all uncovered API definitions.\n```js\nuse(matchApiSchema({\n    apiDefinitionsPath,\n    reportCoverage: true\n}));\n```\n\n```bash\n* API definitions coverage report *\n\nUncovered API definitions found:\n*ROUTE*                    | *METHOD*   | *STATUSES* \n/v2/pet                    | POST       | 405        \n/v2/pet                    | PUT        | 400,404,405\n/v2/pet/findByStatus       | GET        | 200,400    \n/v2/pet/findByTags         | GET        | 200,400    \n/v2/pet/:petId             | GET        | 400,404    \n/v2/pet/:petId             | POST       | 405        \n/v2/pet/:petId             | DELETE     | 400,404    \n/v2/pet/:petId/uploadImage | POST       | 200         \n```\n\n# Exporting the report: \nWhen providing `exportCoverage: true` a `coverage.json` file will be created in your cwd with following structure: \n```js\nuse(matchApiSchema({\n    apiDefinitionsPath,\n    exportCoverage: true\n}));\n```\ncoverage.json:\n```js\n[{\"route\":\"/v2/pet\",\"method\":\"POST\",\"statuses\":\"405\"},\n{\"route\":\"/v2/pet\",\"method\":\"PUT\",\"statuses\":\"400,404,405\"},\n{\"route\":\"/v2/pet/:petId\",\"method\":\"GET\",\"statuses\":\"200\"},\n{\"route\":\"/v2/pet/:petId\",\"method\":\"POST\",\"statuses\":\"405\"},\n{\"route\":\"/v2/pet/:petId\",\"method\":\"DELETE\",\"statuses\":\"404\"}]\n```\n## Supported request libraries\n- supertest\n- axios\n- request-promise*\n- more to come\n\n*\\* When using request-promise `resolveWithFullResponse:true` must be added to the request options, in order to properly extract the request details*\n\n## Supported assertion libraries\n- chai.js\n- should.js\n- jest\n- more to come\n\n\u003c!-- The validation function itself is also exposed, allowing this plugin to be assertion-library agnostic. --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpayu%2Fapi-contract-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpayu%2Fapi-contract-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpayu%2Fapi-contract-validator/lists"}