{"id":15091402,"url":"https://github.com/openapitools/openapi-diff","last_synced_at":"2025-05-14T12:09:48.067Z","repository":{"id":36960536,"uuid":"113924383","full_name":"OpenAPITools/openapi-diff","owner":"OpenAPITools","description":"Utility for comparing two OpenAPI specifications.","archived":false,"fork":false,"pushed_at":"2025-04-03T09:50:23.000Z","size":1457,"stargazers_count":901,"open_issues_count":65,"forks_count":163,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-11T04:57:59.113Z","etag":null,"topics":["api","diff","openapi","openapi-diff","openapi-specification","openapi3","swagger"],"latest_commit_sha":null,"homepage":null,"language":"Java","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/OpenAPITools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2017-12-12T00:39:30.000Z","updated_at":"2025-04-09T13:49:49.000Z","dependencies_parsed_at":"2023-01-17T08:31:31.810Z","dependency_job_id":"e6ffbc82-3743-42ee-a767-63dfef2c97a0","html_url":"https://github.com/OpenAPITools/openapi-diff","commit_stats":{"total_commits":643,"total_committers":58,"mean_commits":"11.086206896551724","dds":0.6049766718506999,"last_synced_commit":"e415cf304be4e66276c7f722862c89b4f0e23ad0"},"previous_names":["quen2404/openapi-diff"],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenAPITools%2Fopenapi-diff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenAPITools%2Fopenapi-diff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenAPITools%2Fopenapi-diff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenAPITools%2Fopenapi-diff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenAPITools","download_url":"https://codeload.github.com/OpenAPITools/openapi-diff/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248345273,"owners_count":21088244,"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":["api","diff","openapi","openapi-diff","openapi-specification","openapi3","swagger"],"created_at":"2024-09-25T10:40:57.750Z","updated_at":"2025-05-14T12:09:48.036Z","avatar_url":"https://github.com/OpenAPITools.png","language":"Java","readme":"# OpenAPI-diff \n\nCompare two OpenAPI specifications (3.x) and render the difference to HTML plaintext, Markdown files, or JSON files.\n\n[![Build](https://github.com/OpenAPITools/openapi-diff/workflows/Main%20Build/badge.svg)](https://github.com/OpenAPITools/openapi-diff/actions?query=branch%3Amaster+workflow%3A\"Main+Build\")\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=OpenAPITools_openapi-diff\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=OpenAPITools_openapi-diff)\n\n[![Maven Central](https://img.shields.io/maven-central/v/org.openapitools.openapidiff/openapi-diff-core)](https://search.maven.org/artifact/org.openapitools.openapidiff/openapi-diff-core)\n\n[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/OpenAPITools/openapi-diff)\n[![Join the Slack chat room](https://img.shields.io/badge/Slack-Join%20the%20chat%20room-orange)](https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g)\n\n[![Docker Automated build](https://img.shields.io/docker/automated/openapitools/openapi-diff)](https://hub.docker.com/r/openapitools/openapi-diff)\n[![Docker Image Version](https://img.shields.io/docker/v/openapitools/openapi-diff?sort=semver)](https://hub.docker.com/r/openapitools/openapi-diff/tags)\n\n# Requirements\n\n* Java 8\n\n# Feature\n\n* Supports OpenAPI spec v3.0.\n* Depth comparison of parameters, responses, endpoint, http method (GET,POST,PUT,DELETE...)\n* Supports swagger api Authorization\n* Render difference of property with Expression Language\n* HTML, Markdown, Asciidoc \u0026 JSON render\n\n# Maven\n\nAvailable on [Maven Central](https://search.maven.org/artifact/org.openapitools.openapidiff/openapi-diff-core)\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.openapitools.openapidiff\u003c/groupId\u003e\n  \u003cartifactId\u003eopenapi-diff-core\u003c/artifactId\u003e\n  \u003cversion\u003e${openapi-diff-version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n# Homebrew\nAvailable for Mac users on [brew](https://formulae.brew.sh/formula/openapi-diff)\n\n```bash\nbrew install openapi-diff\n```\nUsage instructions in [Usage -\u003e Command line](#command-line)\n\n# Docker\n\nAvailable on [Docker Hub](https://hub.docker.com/r/openapitools/openapi-diff/) as `openapitools/openapi-diff`.\n\n```bash\n# docker run openapitools/openapi-diff:latest\nusage: openapi-diff \u003cold\u003e \u003cnew\u003e\n    --asciidoc \u003cfile\u003e           export diff as asciidoc in given file\n    --debug                     Print debugging information\n    --error                     Print error information\n    --fail-on-changed           Fail if API changed but is backward\n                                compatible\n    --fail-on-incompatible      Fail only if API changes broke backward\n                                compatibility\n    --config-file               Config file to override default behavior. Supported file formats: .yaml\n    --config-prop               Config property to override default behavior with key:value format (e.g. my.prop:true)\n -h,--help                      print this message\n    --header \u003cproperty=value\u003e   use given header for authorisation\n    --html \u003cfile\u003e               export diff as html in given file\n    --info                      Print additional information\n    --json \u003cfile\u003e               export diff as json in given file\n -l,--log \u003clevel\u003e               use given level for log (TRACE, DEBUG,\n                                INFO, WARN, ERROR, OFF). Default: ERROR\n    --markdown \u003cfile\u003e           export diff as markdown in given file\n    --off                       No information printed\n    --query \u003cproperty=value\u003e    use query param for authorisation\n    --state                     Only output diff state: no_changes,\n                                incompatible, compatible\n    --text \u003cfile\u003e               export diff as text in given file\n    --trace                     be extra verbose\n    --version                   print the version information and exit\n    --warn                      Print warning information\n```\n\n## Build the image\n\nThis is only required if you want to try new changes in the Dockerfile of this project.\n\n```bash\ndocker build -t local-openapi-diff .\n```\n\nYou can replace the local image name `local-openapi-diff` by any name of your choice.\n\n## Run an instance\n\nIn this example the `$(pwd)/core/src/test/resources` directory is mounted in the `/specs` directory of the container\nin readonly mode (`ro`).\n\n```bash\ndocker run --rm -t \\\n  -v $(pwd)/core/src/test/resources:/specs:ro \\\n  openapitools/openapi-diff:latest /specs/path_1.yaml /specs/path_2.yaml\n```\n\nThe remote name `openapitools/openapi-diff` can be replaced with `local-openapi-diff` or the name you gave to your local image.\n\n# Usage\n\nopenapi-diff can read OpenAPI specs from JSON files or HTTP URLs.\n\n## Command Line\n\n```bash\n$ openapi-diff --help\nusage: openapi-diff \u003cold\u003e \u003cnew\u003e\n    --asciidoc \u003cfile\u003e           export diff as asciidoc in given file\n    --debug                     Print debugging information\n    --error                     Print error information\n -h,--help                      print this message\n    --header \u003cproperty=value\u003e   use given header for authorisation\n    --html \u003cfile\u003e               export diff as html in given file\n    --info                      Print additional information\n    --json \u003cfile\u003e               export diff as json in given file\n -l,--log \u003clevel\u003e               use given level for log (TRACE, DEBUG,\n                                INFO, WARN, ERROR, OFF). Default: ERROR\n    --markdown \u003cfile\u003e           export diff as markdown in given file\n    --off                       No information printed\n    --query \u003cproperty=value\u003e    use query param for authorisation\n    --state                     Only output diff state: no_changes,\n                                incompatible, compatible\n    --fail-on-incompatible      Fail only if API changes broke backward compatibility\n    --fail-on-changed           Fail if API changed but is backward compatible\n    --config-file               Config file to override default behavior. Supported file formats: .yaml\n    --config-prop               Config property to override default behavior with key:value format (e.g. my.prop:true)\n    --trace                     be extra verbose\n    --version                   print the version information and exit\n    --warn                      Print warning information\n```\n\n## Maven Plugin\n\nAdd openapi-diff to your POM to show diffs when you test your Maven project. You may opt to throw an error if you have broken backwards compatibility or if your API has changed.  \n\n```xml\n\u003cplugin\u003e\n  \u003cgroupId\u003eorg.openapitools.openapidiff\u003c/groupId\u003e\n  \u003cartifactId\u003eopenapi-diff-maven\u003c/artifactId\u003e\n  \u003cversion\u003e${openapi-diff-version}\u003c/version\u003e\n  \u003cexecutions\u003e\n    \u003cexecution\u003e\n      \u003cgoals\u003e\n        \u003cgoal\u003ediff\u003c/goal\u003e\n      \u003c/goals\u003e\n      \u003cconfiguration\u003e\n        \u003c!-- Reference specification (perhaps your prod schema) --\u003e\n        \u003coldSpec\u003ehttps://petstore3.swagger.io/api/v3/openapi.json\u003c/oldSpec\u003e\n        \u003c!-- Specification generated by your project in the compile phase --\u003e\n        \u003cnewSpec\u003e${project.basedir}/target/openapi.yaml\u003c/newSpec\u003e\n        \u003c!-- Fail only if API changes broke backward compatibility (default: false) --\u003e\n        \u003cfailOnIncompatible\u003etrue\u003c/failOnIncompatible\u003e\n        \u003c!-- Fail if API changed (default: false) --\u003e\n        \u003cfailOnChanged\u003etrue\u003c/failOnChanged\u003e\n        \u003c!-- Supply file path for console output to file if desired. --\u003e\n        \u003cconsoleOutputFileName\u003e${project.basedir}/../maven/target/diff.txt\u003c/consoleOutputFileName\u003e\n        \u003c!-- Supply file path for json output to file if desired. --\u003e\n        \u003cjsonOutputFileName\u003e${project.basedir}/../maven/target/diff.json\u003c/jsonOutputFileName\u003e\n        \u003c!-- Supply file path for markdown output to file if desired. --\u003e\n        \u003cmarkdownOutputFileName\u003e${project.basedir}/../maven/target/diff.md\u003c/markdownOutputFileName\u003e\n        \u003c!-- Supply config file(s), e.g. to disable incompatibility checks. Later files override earlier files --\u003e\n        \u003cconfigFiles\u003e\n          \u003cconfigFile\u003emy/config-file.yaml\u003c/configFile\u003e\n        \u003c/configFiles\u003e\n        \u003c!-- Supply config properties, e.g. to disable incompatibility checks. Overrides configFiles. --\u003e\n        \u003cconfigProps\u003e\n          \u003cincompatible.response.enum.increased\u003efalse\u003c/incompatible.response.enum.increased\u003e\n        \u003c/configProps\u003e\n      \u003c/configuration\u003e\n    \u003c/execution\u003e\n  \u003c/executions\u003e\n\u003c/plugin\u003e\n```\n\n## Direct Invocation\n\n```java\npublic class Main {\n    public static final String OPENAPI_DOC1 = \"petstore_v3_1.json\";\n    public static final String OPENAPI_DOC2 = \"petstore_v2_2.yaml\";\n        \n    public static void main(String[] args) {\n        ChangedOpenApi diff = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2);\n\n        //...\n    }\n}\n```\n\n### Render difference\n\n---\n#### HTML\n\n```java\nHtmlRender htmlRender = new HtmlRender(\"Changelog\", \"http://deepoove.com/swagger-diff/stylesheets/demo.css\");\nFileOutputStream outputStream = new FileOutputStream(\"testDiff.html\");\nOutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);\nhtmlRender.render(diff, outputStreamWriter);\n```\n\n#### Markdown\n\n```java\nMarkdownRender markdownRender = new MarkdownRender();\nFileOutputStream outputStream = new FileOutputStream(\"testDiff.md\");\nOutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);\nmarkdownRender.render(diff, outputStreamWriter);\n```\n\n#### Asciidoc\n\n```java\nAsciidocRender asciidocRender = new AsciidocRender();\nFileOutputStream outputStream = new FileOutputStream(\"testDiff.adoc\");\nOutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);\nasciidocRender.render(diff, outputStreamWriter);\n```\n\n#### JSON\n\n```java\nJsonRender jsonRender = new JsonRender();\nFileOutputStream outputStream = new FileOutputStream(\"testDiff.json\");\nOutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);\njsonRender.render(diff, outputStreamWriter);\n```\n\n### Extensions\n\nThis project uses Java Service Provider Inteface (SPI) so additional extensions can be added. \n\nTo build your own extension, you simply need to create a `src/main/resources/META-INF/services/org.openapitools.openapidiff.core.compare.ExtensionDiff` file with the full classname of your implementation.\nYour class must also implement the `org.openapitools.openapidiff.core.compare.ExtensionDiff` interface.\nThen, including your library with the `openapi-diff` module will cause it to be triggered automatically.\n\n# Examples\n\n### CLI Output\n\n```text\n==========================================================================\n==                            API CHANGE LOG                            ==\n==========================================================================\n                             Swagger Petstore                             \n--------------------------------------------------------------------------\n--                              What's New                              --\n--------------------------------------------------------------------------\n- GET    /pet/{petId}\n\n--------------------------------------------------------------------------\n--                            What's Deleted                            --\n--------------------------------------------------------------------------\n- POST   /pet/{petId}\n\n--------------------------------------------------------------------------\n--                          What's Deprecated                           --\n--------------------------------------------------------------------------\n- GET    /user/logout\n\n--------------------------------------------------------------------------\n--                            What's Changed                            --\n--------------------------------------------------------------------------\n- PUT    /pet\n  Request:\n        - Deleted application/xml\n        - Changed application/json\n          Schema: Backward compatible\n- POST   /pet\n  Parameter:\n    - Add tags in query\n  Request:\n        - Changed application/xml\n          Schema: Backward compatible\n        - Changed application/json\n          Schema: Backward compatible\n- GET    /pet/findByStatus\n  Parameter:\n    - Deprecated status in query\n  Return Type:\n    - Changed 200 OK\n      Media types:\n        - Changed application/xml\n          Schema: Broken compatibility\n        - Changed application/json\n          Schema: Broken compatibility\n- GET    /pet/findByTags\n  Return Type:\n    - Changed 200 OK\n      Media types:\n        - Changed application/xml\n          Schema: Broken compatibility\n        - Changed application/json\n          Schema: Broken compatibility\n- DELETE /pet/{petId}\n  Parameter:\n    - Add newHeaderParam in header\n- POST   /pet/{petId}/uploadImage\n  Parameter:\n    - Changed petId in path\n- POST   /user\n  Request:\n        - Changed application/json\n          Schema: Backward compatible\n- POST   /user/createWithArray\n  Request:\n        - Changed application/json\n          Schema: Backward compatible\n- POST   /user/createWithList\n  Request:\n        - Changed application/json\n          Schema: Backward compatible\n- GET    /user/login\n  Parameter:\n    - Delete password in query\n- GET    /user/logout\n- GET    /user/{username}\n  Return Type:\n    - Changed 200 OK\n      Media types:\n        - Changed application/xml\n          Schema: Broken compatibility\n        - Changed application/json\n          Schema: Broken compatibility\n- PUT    /user/{username}\n  Request:\n        - Changed application/json\n          Schema: Backward compatible\n--------------------------------------------------------------------------\n--                                Result                                --\n--------------------------------------------------------------------------\n                 API changes broke backward compatibility                 \n--------------------------------------------------------------------------\n```\n\n### Markdown\n\n```markdown\n### What's New\n---\n* `GET` /pet/{petId} Find pet by ID\n\n### What's Deleted\n---\n* `POST` /pet/{petId} Updates a pet in the store with form data\n\n### What's Deprecated\n---\n* `GET` /user/logout Logs out current logged in user session\n\n### What's Changed\n---\n* `PUT` /pet Update an existing pet  \n    Request\n\n        Deleted request body : [application/xml]\n        Changed response : [application/json]\n* `POST` /pet Add a new pet to the store  \n    Parameter\n\n        Add tags //add new query param demo\n    Request\n\n        Changed response : [application/xml]\n        Changed response : [application/json]\n* `GET` /pet/findByStatus Finds Pets by status  \n    Parameter\n\n    Return Type\n\n        Changed response : [200] //successful operation\n* `GET` /pet/findByTags Finds Pets by tags  \n    Return Type\n\n        Changed response : [200] //successful operation\n* `DELETE` /pet/{petId} Deletes a pet  \n    Parameter\n\n        Add newHeaderParam\n* `POST` /pet/{petId}/uploadImage uploads an image for pet  \n    Parameter\n\n        petId Notes ID of pet to update change into ID of pet to update, default false\n* `POST` /user Create user  \n    Request\n\n        Changed response : [application/json]\n* `POST` /user/createWithArray Creates list of users with given input array  \n    Request\n\n        Changed response : [application/json]\n* `POST` /user/createWithList Creates list of users with given input array  \n    Request\n\n        Changed response : [application/json]\n* `GET` /user/login Logs user into the system  \n    Parameter\n\n        Delete password //The password for login in clear text\n* `GET` /user/logout Logs out current logged in user session  \n* `PUT` /user/{username} Updated user  \n    Request\n\n        Changed response : [application/json]\n* `GET` /user/{username} Get user by user name  \n    Return Type\n\n        Changed response : [200] //successful operation\n```\n\n### JSON\n\n```json\n{\n    \"changedElements\": [...],\n    \"changedExtensions\": null,\n    \"changedOperations\": [...],\n    \"compatible\": false,\n    \"deprecatedEndpoints\": [...],\n    \"different\": true,\n    \"incompatible\": true,\n    \"missingEndpoints\": [...],\n    \"newEndpoints\": [\n        {\n            \"method\": \"GET\",\n            \"operation\": {\n                \"callbacks\": null,\n                \"deprecated\": null,\n                \"description\": \"Returns a single pet\",\n                \"extensions\": null,\n                \"externalDocs\": null,\n                \"operationId\": \"getPetById\",\n                \"parameters\": [\n                    {\n                        \"$ref\": null,\n                        \"allowEmptyValue\": null,\n                        \"allowReserved\": null,\n                        \"content\": null,\n                        \"deprecated\": null,\n                        \"description\": \"ID of pet to return\",\n                        \"example\": null,\n                        \"examples\": null,\n                        \"explode\": false,\n                        \"extensions\": null,\n                        \"in\": \"path\",\n                        \"name\": \"petId\",\n                        \"required\": true,\n                        \"schema\": {...},\n                        \"style\": \"SIMPLE\"\n                    }\n                ],\n                \"requestBody\": null,\n                \"responses\": {...},\n                \"security\": [\n                    {\n                        \"api_key\": []\n                    }\n                ],\n                \"servers\": null,\n                \"summary\": \"Find pet by ID\",\n                \"tags\": [\n                    \"pet\"\n                ]\n            },\n            \"path\": null,\n            \"pathUrl\": \"/pet/{petId}\",\n            \"summary\": \"Find pet by ID\"\n        }\n    ],\n    \"newSpecOpenApi\": {...},\n    \"oldSpecOpenApi\": {...},\n    \"unchanged\": false\n}\n```\n\n# License\n\nopenapi-diff is released under the Apache License 2.0.\n\n# Thanks\n\n* Adarsh Sharma / [adarshsharma](https://github.com/adarshsharma)\n* Quentin Desramé / [quen2404](https://github.com/quen2404)\n* [Sayi](https://github.com/Sayi) for his project [swagger-diff](https://github.com/Sayi/swagger-diff) \n  which was a source of inspiration for this tool\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenapitools%2Fopenapi-diff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenapitools%2Fopenapi-diff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenapitools%2Fopenapi-diff/lists"}