MCPcopy Index your code
hub / github.com/OpenAPITools/openapi-diff

github.com/OpenAPITools/openapi-diff @2.1.7

Chat with this repo
repository ↗ · DeepWiki ↗ · release 2.1.7 ↗ · + Follow
1,569 symbols 4,874 edges 164 files 21 documented · 1%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

OpenAPI-diff

Compare two OpenAPI specifications (3.x) and render the difference to HTML plain text, Markdown files, or JSON files.

Build Quality Gate Status

Maven Central

Contribute with Gitpod Join the Slack chat room

Docker Automated build Docker Image Version

Requirements

  • Java 8

Feature

  • Supports OpenAPI spec v3.0.
  • In-depth comparison of parameters, responses, endpoint, http method (GET,POST,PUT,DELETE...)
  • Supports swagger api Authorization
  • Render difference of property with Expression Language
  • HTML, Markdown, Asciidoc & JSON render

Maven

Available on Maven Central

<dependency>
  <groupId>org.openapitools.openapidiff</groupId>
  <artifactId>openapi-diff-core</artifactId>
  <version>${openapi-diff-version}</version>
</dependency>

Homebrew

Available for Mac users on brew

brew install openapi-diff

Usage instructions in Usage -> Command line

Docker

Available on Docker Hub as openapitools/openapi-diff.

# docker run openapitools/openapi-diff:latest
usage: openapi-diff <old> <new>
    --asciidoc <file>           export diff as asciidoc in given file
    --debug                     Print debugging information
    --error                     Print error information
    --fail-on-changed           Fail if API changed but is backward
                                compatible
    --fail-on-incompatible      Fail only if API changes broke backward
                                compatibility
    --config-file               Config file to override default behavior. Supported file formats: .yaml
    --config-prop               Config property to override default behavior with key:value format (e.g. my.prop:true)
 -h,--help                      print this message
    --header <property=value>   use given header for authorisation
    --html <file>               export diff as html in given file
    --info                      Print additional information
    --json <file>               export diff as json in given file
 -l,--log <level>               use given level for log (TRACE, DEBUG,
                                INFO, WARN, ERROR, OFF). Default: ERROR
    --markdown <file>           export diff as markdown in given file
    --off                       No information printed
    --query <property=value>    use query param for authorisation
    --state                     Only output diff state: no_changes,
                                incompatible, compatible
    --text <file>               export diff as text in given file
    --trace                     be extra verbose
    --version                   print the version information and exit
    --warn                      Print warning information

Build the image

This is only required if you want to try new changes in the Dockerfile of this project.

docker build -t local-openapi-diff .

You can replace the local image name local-openapi-diff by any name of your choice.

Run an instance

In this example the $(pwd)/core/src/test/resources directory is mounted in the /specs directory of the container in readonly mode (ro).

docker run --rm -t \
  -v $(pwd)/core/src/test/resources:/specs:ro \
  openapitools/openapi-diff:latest /specs/path_1.yaml /specs/path_2.yaml

The remote name openapitools/openapi-diff can be replaced with local-openapi-diff or the name you gave to your local image.

Usage

openapi-diff can read OpenAPI specs from JSON files or HTTP URLs.

Command Line

$ openapi-diff --help
usage: openapi-diff <old> <new>
    --asciidoc <file>           export diff as asciidoc in given file
    --debug                     Print debugging information
    --error                     Print error information
 -h,--help                      print this message
    --header <property=value>   use given header for authorisation
    --html <file>               export diff as html in given file
    --info                      Print additional information
    --json <file>               export diff as json in given file
 -l,--log <level>               use given level for log (TRACE, DEBUG,
                                INFO, WARN, ERROR, OFF). Default: ERROR
    --markdown <file>           export diff as markdown in given file
    --off                       No information printed
    --query <property=value>    use query param for authorisation
    --state                     Only output diff state: no_changes,
                                incompatible, compatible
    --fail-on-incompatible      Fail only if API changes broke backward compatibility
    --fail-on-changed           Fail if API changed but is backward compatible
    --config-file               Config file to override default behavior. Supported file formats: .yaml
    --config-prop               Config property to override default behavior with key:value format (e.g. my.prop:true)
    --trace                     be extra verbose
    --version                   print the version information and exit
    --warn                      Print warning information

Maven Plugin

Add 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.

<plugin>
  <groupId>org.openapitools.openapidiff</groupId>
  <artifactId>openapi-diff-maven</artifactId>
  <version>${openapi-diff-version}</version>
  <executions>
    <execution>
      <goals>
        <goal>diff</goal>
      </goals>
      <configuration>

        <oldSpec>https://petstore3.swagger.io/api/v3/openapi.json</oldSpec>

        <newSpec>${project.basedir}/target/openapi.yaml</newSpec>

        <failOnIncompatible>true</failOnIncompatible>

        <failOnChanged>true</failOnChanged>

        <consoleOutputFileName>${project.basedir}/../maven/target/diff.txt</consoleOutputFileName>

        <jsonOutputFileName>${project.basedir}/../maven/target/diff.json</jsonOutputFileName>

        <markdownOutputFileName>${project.basedir}/../maven/target/diff.md</markdownOutputFileName>

        <configFiles>
          <configFile>my/config-file.yaml</configFile>
        </configFiles>

        <configProps>
          <incompatible.response.enum.increased>false</incompatible.response.enum.increased>
        </configProps>
      </configuration>
    </execution>
  </executions>
</plugin>

Direct Invocation

public class Main {
    public static final String OPENAPI_DOC1 = "petstore_v3_1.json";
    public static final String OPENAPI_DOC2 = "petstore_v2_2.yaml";

    public static void main(String[] args) {
        ChangedOpenApi diff = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2);

        //...
    }
}

Path Matching while comparing two OpenAPI paths

Path matching controls how paths from the old and new specs are paired during comparison (PathsDiff.java). The default matcher (DefaultPathMatcher) obfuscates path parameter names, meaning /users/{id} matches /users/{userId}. The default matcher fails on ambiguous signatures if the spec contains a few paths semantically identical. In case this behaviour is not fitting your use case, you can implement your own matching strategy.

You can plug in a custom matcher via OpenApiDiffOptions implementing the PathMatcher interface:

OpenApiDiffOptions options = OpenApiDiffOptions
    .builder()
    .pathMatcher(new MyCustomPathMatcher())
    .build();

ChangedOpenApi diff = OpenApiCompare.fromLocations(oldSpec, newSpec, null, options);

Render difference


HTML

HtmlRender htmlRender = new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css");
FileOutputStream outputStream = new FileOutputStream("testDiff.html");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
htmlRender.render(diff, outputStreamWriter);

Markdown

MarkdownRender markdownRender = new MarkdownRender();
FileOutputStream outputStream = new FileOutputStream("testDiff.md");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
markdownRender.render(diff, outputStreamWriter);

Asciidoc

AsciidocRender asciidocRender = new AsciidocRender();
FileOutputStream outputStream = new FileOutputStream("testDiff.adoc");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
asciidocRender.render(diff, outputStreamWriter);

JSON

JsonRender jsonRender = new JsonRender();
FileOutputStream outputStream = new FileOutputStream("testDiff.json");
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
jsonRender.render(diff, outputStreamWriter);

Extensions

This project uses Java Service Provider Interface (SPI) so additional extensions can be added.

To 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. Your class must also implement the org.openapitools.openapidiff.core.compare.ExtensionDiff interface. Then, including your library with the openapi-diff module will cause it to be triggered automatically.

Examples

CLI Output

```text

== API CHANGE LOG ==

                         Swagger Petstore

-- What's New --

  • GET /pet/{petId}

-- What's Deleted --

  • POST /pet/{petId}

-- What's Deprecated --

  • GET /user/logout

-- What's Changed --

  • PUT /pet Request: - Deleted application/xml - Changed application/json Schema: Backward compatible
  • POST /pet Parameter:
    • Add tags in query Request:
      • Changed application/xml Schema: Backward compatible
      • Changed application/json Schema: Backward compatible
  • GET /pet/findByStatus Parameter:
    • Deprecated status in query Return Type:
    • Changed 200 OK Media types:
      • Changed application/xml Schema: Broken compatibility
      • Changed application/json Schema: Broken compatibility
  • GET /pet/findByTags Return Type:
    • Changed 200 OK Media types:
      • Changed application/xml Schema: Broken compatibility
      • Changed application/json Schema: Broken compatibility
  • DELETE /pet/{petId} Parameter:
    • Add newHeaderParam in header
  • POST /pet/{petId}/uploadImage Parameter:
    • Changed petId in path
  • POST /user Request: - Changed application/json Schema: Backward compatible
  • POST /user/createWithArray Request: - Changed application/json Schema: Backward compatible
  • POST /user/createWithList Request: - Changed application/json Schema: Backward compatible
  • GET /user/login Parameter:
    • Delete password in query
  • GET /user/lo

Extension points exported contracts — how you extend this code

Changed (Interface)
(no doc) [18 implementers]
core/src/main/java/org/openapitools/openapidiff/core/model/Changed.java
ComposedChanged (Interface)
(no doc) [22 implementers]
core/src/main/java/org/openapitools/openapidiff/core/model/ComposedChanged.java
Render (Interface)
(no doc) [5 implementers]
core/src/main/java/org/openapitools/openapidiff/core/output/Render.java
PathMatcher (Interface)
Strategy to find a matching path. [2 implementers]
core/src/main/java/org/openapitools/openapidiff/core/compare/matchers/PathMatcher.java
ExtensionDiff (Interface)
(no doc)
core/src/main/java/org/openapitools/openapidiff/core/compare/ExtensionDiff.java

Core symbols most depended-on inside this repo

get
called by 182
core/src/main/java/org/openapitools/openapidiff/core/model/deferred/DeferredChanged.java
with
called by 110
core/src/main/java/org/openapitools/openapidiff/core/model/deferred/DeferredBuilder.java
fromLocations
called by 92
core/src/main/java/org/openapitools/openapidiff/core/OpenApiCompare.java
toString
called by 88
core/src/main/java/org/openapitools/openapidiff/core/model/Change.java
put
called by 85
core/src/main/java/org/openapitools/openapidiff/core/model/deferred/RecursiveSchemaSet.java
safelyAppend
called by 82
core/src/main/java/org/openapitools/openapidiff/core/output/Render.java
ifPresent
called by 64
core/src/main/java/org/openapitools/openapidiff/core/model/deferred/DeferredChanged.java
map
called by 58
core/src/main/java/org/openapitools/openapidiff/core/model/deferred/DeferredChanged.java

Shape

Method 1,400
Class 159
Interface 6
Enum 4

Languages

Java100%

Modules by API surface

core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java82 symbols
core/src/main/java/org/openapitools/openapidiff/core/output/HtmlRender.java40 symbols
core/src/main/java/org/openapitools/openapidiff/core/output/MarkdownRender.java39 symbols
core/src/main/java/org/openapitools/openapidiff/core/model/ChangedParameter.java38 symbols
core/src/main/java/org/openapitools/openapidiff/core/model/ChangedOperation.java36 symbols
core/src/main/java/org/openapitools/openapidiff/core/compare/OpenApiDiff.java36 symbols
core/src/main/java/org/openapitools/openapidiff/core/model/ChangedHeader.java30 symbols
core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSecurityScheme.java29 symbols
core/src/test/java/org/openapitools/openapidiff/core/ParameterDiffTest.java27 symbols
core/src/main/java/org/openapitools/openapidiff/core/model/DiffContext.java27 symbols
core/src/main/java/org/openapitools/openapidiff/core/output/ConsoleRender.java25 symbols
core/src/main/java/org/openapitools/openapidiff/core/output/AsciidocRender.java22 symbols

For agents

$ claude mcp add openapi-diff \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact