### Example: Using JsonRender Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Shows how to instantiate and use JsonRender to write the diff to a file as JSON. ```java Render renderer = new JsonRender(); try (FileWriter fw = new FileWriter("diff.json"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } // Parse JSON in other tools // {"newEndpoints":[...], "missingEndpoints":[...], "changedOperations":[...]} ``` -------------------------------- ### Example: Using MarkdownRender Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Demonstrates using MarkdownRender to generate a Markdown file from the comparison results. ```java Render renderer = new MarkdownRender(); try (FileWriter fw = new FileWriter("diff.md"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } // Output: // # What's Changed // ## New Endpoints // * POST /api/v2/users // ## Changed Endpoints // ### GET /api/users // Parameter removed: limit (incompatible) ``` -------------------------------- ### Example: Using HtmlRender Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Shows how to use HtmlRender to create an HTML file for visual inspection of the diff. ```java Render renderer = new HtmlRender(); try (FileWriter fw = new FileWriter("diff.html"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } // Open diff.html in a web browser for visual inspection ``` -------------------------------- ### Get Schema and Examples Changes Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/RequestResponseModels.md Access the ChangedSchema and ChangedExamples objects to inspect modifications within a specific media type. Use these to understand detailed schema or example value differences. ```java public ChangedSchema getSchema() public ChangedExamples getExamples() ``` -------------------------------- ### Example: Using AsciidocRender Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Demonstrates using AsciidocRender to generate an AsciiDoc file, suitable for Asciidoctor processing. ```java Render renderer = new AsciidocRender(); try (FileWriter fw = new FileWriter("diff.adoc"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } // Generate PDF from AsciiDoc: // asciidoctor -b pdf diff.adoc ``` -------------------------------- ### Example: Rendering Diff to JSON File Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Demonstrates how to obtain a comparison result and render it to a JSON file using JsonRender. ```java ChangedOpenApi diff = OpenApiCompare.fromLocations("old.json", "new.json"); Render renderer = new JsonRender(); try (FileWriter writer = new FileWriter("diff.json")) { renderer.render(diff, new OutputStreamWriter(writer)); } ``` -------------------------------- ### Configuration Precedence Example Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Demonstrates how configuration files and properties are loaded and how precedence is determined. Properties set via configProperty() override YAML file configurations. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("base.yaml")) // Loaded first .configYaml(new File("overrides.yaml")) // Overrides base .configProperty("key", "value") // Overrides file-based config .build(); ``` -------------------------------- ### Install OpenAPI-diff using Homebrew Source: https://github.com/openapitools/openapi-diff/blob/master/README.md Install the OpenAPI-diff command-line tool on macOS using Homebrew for easy access. ```bash brew install openapi-diff ``` -------------------------------- ### Iterating Through New Endpoints Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/types.md Example showing how to loop through new endpoints identified by the diff and print their method, URL, and summary. ```java for (Endpoint endpoint : diff.getNewEndpoints()) { System.out.println("New endpoint: " + endpoint.getMethod() + " " + endpoint.getPathUrl()); System.out.println("Summary: " + endpoint.getSummary()); } ``` -------------------------------- ### ConsoleRender Example Usage Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Demonstrates how to use ConsoleRender to output a diff to System.out. This is suitable for terminal display and piping to files or logs. ```java Render renderer = new ConsoleRender(); try (OutputStreamWriter osw = new OutputStreamWriter(System.out)) { renderer.render(diff, osw); } ``` -------------------------------- ### Minimal OpenAPI Comparison Example Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Compares two OpenAPI specifications from locations, checks for breaking changes, and renders the differences in JSON format to standard output. Ensure the 'specs/api-v1.json' and 'specs/api-v2.json' files exist. ```java import org.openapitools.openapidiff.core.OpenApiCompare; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.JsonRender; // Compare two API specifications ChangedOpenApi diff = OpenApiCompare.fromLocations( "specs/api-v1.json", "specs/api-v2.json" ); // Check compatibility if (diff.isCoreChanged().isIncompatible()) { System.out.println("Breaking changes detected!"); } // Render to JSON new JsonRender().render(diff, new OutputStreamWriter(System.out)); ``` -------------------------------- ### Example YAML configuration for OpenAPI Diff Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/configuration.md A sample YAML file demonstrating how to configure various OpenAPI Diff checks. It includes disabling backward compatibility checks and enabling specific security and operation ID checks. ```yaml # Disable strict checks for backward compatibility incompatible.openapi.endpoints.decreased: false incompatible.request.params.decreased: false incompatible.request.required.increased: false # Enable additional checks incompatible.operation.id.changed: true # Security considerations incompatible.security.requirements.decreased: true incompatible.security.scheme.oauth2.token.url.changed: true ``` -------------------------------- ### Example Usage of DiffResult Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/types.md Demonstrates how to use the DiffResult enum to determine the impact of API changes after a comparison. ```java ChangedOpenApi diff = OpenApiCompare.fromLocations("old.json", "new.json"); DiffResult result = diff.isCoreChanged(); if (result.isIncompatible()) { System.out.println("Breaking changes detected!"); System.exit(1); } else if (result.isCompatible()) { System.out.println("Changes are backward compatible"); } ``` -------------------------------- ### Check for Schema Changes Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/ChangedOpenApi.md This example demonstrates how to iterate through modified schema definitions in the components section and identify those with incompatible changes. ```java for (ChangedSchema schema : diff.getChangedSchemas()) { System.out.println("Schema: " + schema.getName()); if (schema.isIncompatible()) { System.out.println(" Contains incompatible changes"); } } ``` -------------------------------- ### Custom Path Matcher: Exact Match Strategy Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Example of a custom PathMatcher that requires an exact string match for paths. Useful when parameter names must be identical. ```java // Matcher that requires exact path string match PathMatcher exactMatcher = (what, candidates) -> { String whatPath = what.getKey(); return candidates.entrySet().stream() .filter(entry -> entry.getKey().equals(whatPath)) .findFirst(); }; OpenApiDiffOptions options = OpenApiDiffOptions.builder() .pathMatcher(exactMatcher) .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations( "old.json", "new.json", null, options ); ``` -------------------------------- ### Custom YAML Renderer Implementation Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Implement the Render interface to create custom output formats like YAML. This example shows how to access diff details and write them to an output stream. ```java import org.openapitools.openapidiff.core.output.Render; import org.openapitools.openapidiff.core.exception.RendererException; public class YamlRender implements Render { @Override public void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter) throws RendererException { try { // Custom YAML rendering logic // Access diff.getNewEndpoints(), getChangedOperations(), etc. outputStreamWriter.append("openapi_diff:\n"); outputStreamWriter.append(" new_endpoints: " + diff.getNewEndpoints().size()); outputStreamWriter.flush(); } catch (IOException e) { throw new RendererException("YAML rendering failed", e); } } } // Usage: Render renderer = new YamlRender(); try (FileWriter fw = new FileWriter("diff.yaml"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } ``` -------------------------------- ### Configure OpenAPI Diff using environment variables Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/configuration.md Shows how to configure OpenAPI Diff options dynamically based on environment variables, suitable for CI/CD pipelines. This example disables the check for decreased OpenAPI endpoints if the FAIL_ON_INCOMPATIBLE variable is set to 'false'. ```java String failOnIncompatible = System.getenv("FAIL_ON_INCOMPATIBLE"); OpenApiDiffOptions.Builder builder = OpenApiDiffOptions.builder(); if ("false".equals(failOnIncompatible)) { builder.configProperty("incompatible.openapi.endpoints.decreased", "false"); } OpenApiDiffOptions options = builder.build(); ``` -------------------------------- ### Inspect Schema Changes Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/ChangeModels.md This example demonstrates how to iterate through changed schemas and check for type modifications, added properties, removed properties, and modified properties. Useful for detailed schema comparison. ```java for (ChangedSchema schema : diff.getChangedSchemas()) { if (schema.isChangedType()) { System.out.println("Type changed"); } for (String newProp : schema.getIncreasedProperties().keySet()) { System.out.println("Property added: " + newProp); } for (String removedProp : schema.getMissingProperties().keySet()) { System.out.println("Property removed: " + removedProp); } for (Map.Entry entry : schema.getChangedProperties().entrySet()) { System.out.println("Property modified: " + entry.getKey()); } } ``` -------------------------------- ### Example Usage of ChangedRequestBody Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/RequestResponseModels.md Demonstrates how to check for changes in a request body's required status, content, and overall compatibility using the `ChangedRequestBody` model. ```java ChangedOperation op = diff.getChangedOperations().get(0); ChangedRequestBody reqBody = op.getRequestBody(); if (reqBody != null) { if (reqBody.isChangeRequired()) { System.out.println("Request body required status changed"); System.out.println(" Old: " + reqBody.getOldRequestBody().getRequired()); System.out.println(" New: " + reqBody.getNewRequestBody().getRequired()); } if (reqBody.getContent() != null && reqBody.getContent().isChanged().isDifferent()) { System.out.println("Request content types changed"); } if (reqBody.isChanged().isIncompatible()) { System.out.println("Breaking changes in request body"); } } ``` -------------------------------- ### Handle IOException during OpenAPI Comparison Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/errors.md Provides an example of catching RuntimeException and checking if the underlying cause is an IOException, which can occur during file operations or network requests. ```java try { ChangedOpenApi diff = OpenApiCompare.fromLocations( "/specs/old.json", "/specs/new.json" ); } catch (RuntimeException e) { if (e.getCause() instanceof IOException) { System.err.println("I/O error: " + e.getCause().getMessage()); } else { System.err.println("Comparison failed: " + e.getMessage()); } } ``` -------------------------------- ### Robust Error Handling in OpenAPI Comparison Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/UsagePatterns.md This example shows how to perform a diff between two OpenAPI files while implementing comprehensive error handling for various potential issues, including file validation, comparison, and rendering errors. It utilizes try-with-resources for stream management and provides specific exit codes for different error types. ```Java import org.openapitools.openapidiff.core.exception.RendererException; public class RobustDiffComparison { public static void main(String[] args) { try { // Validate inputs File oldFile = validateFile(args[0]); File newFile = validateFile(args[1]); // Compare ChangedOpenApi diff = OpenApiCompare.fromFiles(oldFile, newFile); // Render renderResults(diff, new File("output")); } catch (IllegalArgumentException e) { System.err.println("Configuration error: " + e.getMessage()); System.exit(1); } catch (RendererException e) { System.err.println("Rendering error: " + e.getMessage()); if (e.getCause() != null) { e.getCause().printStackTrace(); } System.exit(2); } catch (RuntimeException e) { System.err.println("Comparison failed: " + e.getMessage()); if (e.getCause() != null) { System.err.println("Cause: " + e.getCause().getMessage()); } System.exit(3); } catch (Exception e) { System.err.println("Unexpected error: " + e.getMessage()); e.printStackTrace(); System.exit(4); } } private static File validateFile(String path) { File f = new File(path); if (!f.exists()) { throw new IllegalArgumentException("File not found: " + path); } if (!f.canRead()) { throw new IllegalArgumentException("Cannot read file: " + path); } return f; } private static void renderResults(ChangedOpenApi diff, File outputDir) { outputDir.mkdirs(); Render[] renderers = { new JsonRender(), new MarkdownRender(), new HtmlRender() }; String[] formats = {"json", "md", "html"}; for (int i = 0; i < renderers.length; i++) { File output = new File(outputDir, "diff." + formats[i]); try (FileWriter fw = new FileWriter(output); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderers[i].render(diff, osw); } catch (IOException e) { System.err.println("Error writing " + output + ": " + e.getMessage()); } } } } ``` -------------------------------- ### Implement Custom Path Matcher Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/UsagePatterns.md Define a custom PathMatcher to control how paths are compared between OpenAPI specifications. This example shows an exact path matching strategy. ```java import org.openapitools.openapidiff.core.compare.matchers.PathMatcher; import io.swagger.v3.oas.models.PathItem; import java.util.Map; import java.util.Optional; // Custom matcher that requires exact path match PathMatcher customMatcher = (what, candidates) -> { String whatPath = what.getKey(); return candidates.entrySet().stream() .filter(entry -> entry.getKey().equals(whatPath)) .findFirst(); }; OpenApiDiffOptions options = OpenApiDiffOptions.builder() .pathMatcher(customMatcher) .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations( "old.json", "new.json", null, options ); ``` -------------------------------- ### Direct Java Invocation for OpenAPI Diff Source: https://github.com/openapitools/openapi-diff/blob/master/README.md Demonstrates how to directly invoke OpenAPI Diff using its Java API. This example shows how to create a diff object from two OpenAPI specification locations. ```java 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); //... } } ``` -------------------------------- ### Iterate Through Header Changes Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/RequestResponseModels.md Iterate through new, removed, and modified headers within a response. This example demonstrates how to log details about each type of header change detected. ```java ChangedHeaders headers = response.getHeaders(); if (headers != null && headers.isChanged().isDifferent()) { // New headers added for (String headerName : headers.getIncreased().keySet()) { System.out.println("New header: " + headerName); } // Headers removed for (String headerName : headers.getMissing().keySet()) { System.out.println("Removed header: " + headerName); } // Header details changed for (Map.Entry entry : headers.getChanged().entrySet()) { System.out.println("Header modified: " + entry.getKey()); } } ``` -------------------------------- ### Get Path Matcher Strategy Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Retrieve the currently set path matching strategy from the OpenApiDiffOptions object. Returns the default matcher if none was explicitly set. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder().build(); PathMatcher matcher = options.getPathMatcher(); // matcher is DefaultPathMatcher ``` -------------------------------- ### Streaming Output Rendering Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Utilizes the modern streaming approach for rendering API diffs to an OutputStreamWriter, which is recommended for large diffs to prevent memory issues. This example uses JsonRender. ```java Render renderer = new JsonRender(); try (FileWriter fw = new FileWriter("diff.json"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); // Streams output } ``` -------------------------------- ### Initialize OpenApiDiffOptions with Configuration Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/configuration.md Demonstrates how to initialize `OpenApiDiffOptions` by setting configuration properties and providing a YAML config file. This is useful for applying multiple custom checks. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configProperty("incompatible.openapi.endpoints.decreased", "false") .configProperty("incompatible.request.params.decreased", "false") .configYaml(new File("config.yaml")) .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations("old.json", "new.json", null, options); ``` -------------------------------- ### Loading Configuration from Multiple YAML Files and Properties Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Demonstrates how to build OpenApiDiffOptions by layering configuration from default YAML files and overriding specific properties. Later configurations override earlier ones. ```java // Create a base configuration File baseConfig = new File("config/defaults.yaml"); // Level 1 File envConfig = new File("config/production.yaml"); // Level 2 OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(baseConfig) // Loaded first .configYaml(envConfig) // Overrides baseConfig .configProperty("incompatible.openapi.endpoints.decreased", "false") // Override everything .build(); ``` -------------------------------- ### OpenApiDiffOptions Builder Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Demonstrates how to create an OpenApiDiffOptions object using the fluent builder pattern, including loading from a YAML file, setting properties, and applying a custom path matcher. ```APIDOC ## Builder Pattern Create options using the fluent builder: ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("config.yaml")) .configProperty("incompatible.openapi.endpoints.decreased", "false") .pathMatcher(new CustomPathMatcher()) .build(); ``` ``` -------------------------------- ### Get All Changed Elements Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/ChangedOpenApi.md Retrieve a flat list of all modified components, including operations, schemas, and extensions, using the `getChangedElements()` method. ```java public List getChangedElements() ``` -------------------------------- ### General Usage Pattern: Compare Specs and Render to File Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Shows the typical workflow for comparing two OpenAPI specifications and rendering the differences to a file using MarkdownRender. This involves fetching specifications, creating a renderer, and writing the output. ```java // 1. Compare specifications ChangedOpenApi diff = OpenApiCompare.fromLocations( "https://api.example.com/spec/v1", "https://api.example.com/spec/v2" ); // 2. Create renderer Render renderer = new MarkdownRender(); // 3. Write to file try (FileWriter fw = new FileWriter("changes.md"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } catch (IOException e) { e.printStackTrace(); } ``` -------------------------------- ### ChangedOperation Example Usage Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/ChangeModels.md Iterates through changed operations to identify modifications in HTTP method, path, parameters, request body, responses, and deprecation status. ```java for (ChangedOperation op : diff.getChangedOperations()) { System.out.println(op.getHttpMethod() + " " + op.getPathUrl()); if (op.getParameters() != null && op.getParameters().isChanged().isDifferent()) { System.out.println(" Parameters changed"); } if (op.resultRequestBody().isIncompatible()) { System.out.println(" Request body changed incompatibly"); } if (op.resultApiResponses().isIncompatible()) { System.out.println(" Response changed incompatibly"); } if (op.isDeprecated()) { System.out.println(" Operation deprecated"); } } ``` -------------------------------- ### Compile and Run Unit Tests Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Use this command to compile all modules and run their unit tests. It's a fundamental step for verifying code changes. ```bash ./mvnw test ``` -------------------------------- ### Get Increased, Missing, and Changed Headers Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/RequestResponseModels.md Retrieve maps of headers that were added, removed, or modified. This is essential for tracking header-level changes in API responses. ```java public Map getIncreased() public Map getMissing() public Map getChanged() ``` -------------------------------- ### Create OpenApiDiffOptions using Builder Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Instantiate OpenApiDiffOptions using the fluent builder pattern, setting configuration from a file, individual properties, and a custom path matcher. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("config.yaml")) .configProperty("incompatible.openapi.endpoints.decreased", "false") .pathMatcher(new CustomPathMatcher()) .build(); ``` -------------------------------- ### getPathMatcher() - Get path matching strategy Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Retrieves the currently set path matching strategy. Returns the default matcher if none was explicitly set. ```APIDOC ## getPathMatcher() Get the path matching strategy (custom or default). ```java public PathMatcher getPathMatcher() ``` **Return**: `PathMatcher` — Path matching implementation; returns `DefaultPathMatcher` if none was set **Example**: ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder().build(); PathMatcher matcher = options.getPathMatcher(); // matcher is DefaultPathMatcher ``` ``` -------------------------------- ### Clean Build and Verification Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Performs a clean build by removing previous build artifacts before running the verification process. Use this to ensure a fresh build state. ```bash ./mvnw clean verify ``` -------------------------------- ### OpenAPI Diff Command Line Help Source: https://github.com/openapitools/openapi-diff/blob/master/README.md Displays the help message for the openapi-diff command-line tool, listing all available options and their descriptions. ```bash $ openapi-diff --help usage: openapi-diff --asciidoc export diff as asciidoc in given file --debug Print debugging information --error Print error information -h,--help print this message --header use given header for authorisation --html export diff as html in given file --info Print additional information --json export diff as json in given file -l,--log use given level for log (TRACE, DEBUG, INFO, WARN, ERROR, OFF). Default: ERROR --markdown export diff as markdown in given file --off No information printed --query 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 ``` -------------------------------- ### Creating and Using Authorization Values Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/types.md Demonstrates how to create a list of AuthorizationValue objects and use them with OpenApiCompare to compare API specifications from different locations. ```java List auths = new ArrayList<>(); auths.add(new AuthorizationValue("Authorization", "Bearer token123", "header")); auths.add(new AuthorizationValue("api_key", "secret", "query")); ChangedOpenApi diff = OpenApiCompare.fromLocations( "https://api.example.com/spec", "https://api.example.com/spec-new", auths ); ``` -------------------------------- ### Build Single Module and Dependencies Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Compiles and verifies a specific module along with its dependencies. Useful for targeted development and testing. ```bash ./mvnw -pl core -am verify ``` ```bash ./mvnw -pl cli -am package ``` -------------------------------- ### DiffContext Methods for Accessing Information Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Shows how to access configuration, URL, method, parameters, and other state information from the DiffContext during comparison operations. ```java // Access context information public OpenApiDiffOptions getOptions() public Configuration getConfig() public String getUrl() public PathItem.HttpMethod getMethod() public Map getParameters() public Boolean isRequired() public boolean isResponse() public boolean isRequest() public String getLeftUrl() public String getRightUrl() ``` -------------------------------- ### OpenApiCompare Methods Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/INDEX.md Static methods to create an OpenApiCompare instance from various sources like URLs, files, or content strings. ```APIDOC ## OpenApiCompare.fromLocations ### Description Compares two OpenAPI specifications by providing their URLs. ### Method Static method call ### Parameters - **oldUrl** (string) - Required - URL of the old OpenAPI specification. - **newUrl** (string) - Required - URL of the new OpenAPI specification. ### Endpoint N/A (Library method) ## OpenApiCompare.fromFiles ### Description Compares two OpenAPI specifications by providing their file paths. ### Method Static method call ### Parameters - **oldFile** (string) - Required - Path to the old OpenAPI specification file. - **newFile** (string) - Required - Path to the new OpenAPI specification file. ### Endpoint N/A (Library method) ## OpenApiCompare.fromContents ### Description Compares two OpenAPI specifications by providing their content as strings. ### Method Static method call ### Parameters - **oldContent** (string) - Required - Content of the old OpenAPI specification. - **newContent** (string) - Required - Content of the new OpenAPI specification. ### Endpoint N/A (Library method) ## OpenApiCompare.fromSpecifications ### Description Compares two OpenAPI specifications provided as objects. ### Method Static method call ### Parameters - **oldSpec** (object) - Required - The old OpenAPI specification object. - **newSpec** (object) - Required - The new OpenAPI specification object. ### Endpoint N/A (Library method) ``` -------------------------------- ### Full CI-Style Verification Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Executes a comprehensive verification process including unit tests and packaging, mirroring the CI environment. This ensures the project builds and passes all checks. ```bash ./mvnw verify ``` -------------------------------- ### Get Old and New Media Type Objects Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/RequestResponseModels.md Retrieve the old and new MediaType objects for detailed comparison. This is useful when you need to access specific properties of the media types before and after the change. ```java public MediaType getOldMediaType() public MediaType getNewMediaType() ``` -------------------------------- ### Handle Configuration Error Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/errors.md Demonstrates catching an IllegalArgumentException when attempting to build OpenApiDiffOptions with a non-existent configuration file. ```java try { OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("/nonexistent/config.yaml")) .build(); } catch (IllegalArgumentException e) { // "Problem loading config. file=/nonexistent/config.yaml" } ``` -------------------------------- ### Load Configuration from YAML File Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Use the configYaml method to load OpenAPI diff comparison settings from a specified YAML file. Ensure the file is readable and correctly formatted. ```java Builder builder = OpenApiDiffOptions.builder(); builder.configYaml(new File("/etc/openapi-diff/config.yaml")); OpenApiDiffOptions options = builder.build(); ``` -------------------------------- ### Self-Referential Schema Example Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md This YAML snippet illustrates a self-referential schema definition within the components section, where a 'User' schema references itself using a '$ref'. This is handled by the library's schema caching mechanism. ```yaml components: schemas: User: properties: id: type: integer friend: $ref: '#/components/schemas/User' # Self-reference ``` -------------------------------- ### Accessing Configuration Properties in Code Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Shows how to set configuration properties during builder initialization and then retrieve them using the Configuration object within your code. Supports boolean and string types with default values. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configProperty("custom.check.enabled", "true") .build(); // In your code: Configuration config = options.getConfig(); boolean isEnabled = config.getBoolean("custom.check.enabled", false); String value = config.getString("some.key", "default"); ``` -------------------------------- ### Build Docker Image Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Builds a Docker image using the project's Dockerfile. This command should be run after building the shaded JAR for the CLI. ```bash docker build -t local-openapi-diff . ``` -------------------------------- ### Usage Patterns Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Illustrates common patterns for using the openapi-diff library, covering basic comparison, detailed analysis, output rendering, configuration, integration with CI/CD pipelines, and error handling. ```APIDOC ## Usage Patterns ### Description Provides practical examples and common patterns for utilizing the openapi-diff library in various scenarios, from basic comparisons to advanced integration and error handling. ### Patterns Covered - **Basic Comparison**: Comparing specs from files, URLs, or directly from content. - **Analysis**: Analyzing differences at the endpoint, operation, parameter, and response levels. - **Output Rendering**: Generating reports in JSON, Markdown, HTML, and other formats. - **Configuration**: Applying custom configurations, ignoring certain changes, and using YAML config files. - **Integration**: Integrating with CI/CD pipelines for automated validation and reporting. - **Error Handling**: Strategies for managing exceptions during comparison and rendering. ``` -------------------------------- ### Build Shaded JAR for CLI Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Compiles and packages the CLI module into a shaded JAR, including all its dependencies. This is a prerequisite for running the CLI from source. ```bash ./mvnw -pl cli -am package ``` -------------------------------- ### OpenApiDiffOptions Configuration Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Allows for fluent configuration of the comparison behavior using a builder pattern. Supports loading configurations from YAML files and overriding properties, including custom PathMatcher strategies and backward incompatibility checks. ```APIDOC ## OpenApiDiffOptions ### Description Configuration object for controlling the behavior of the OpenAPI comparison. It supports a builder pattern for easy configuration and can load settings from YAML files. ### Usage ```java import org.openapitools.openapidiff.core.OpenApiCompare; import org.openapitools.openapidiff.core.model.OpenApiDiffOptions; OpenApiDiffOptions options = new OpenApiDiffOptions.Builder() .withIgnoreMissingSchemas(true) .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations("specs/api-v1.json", "specs/api-v2.json", options); ``` ### Features - Builder pattern for fluent configuration. - Support for YAML configuration files. - Property overrides. - Custom `PathMatcher` strategy. - Backward incompatibility check configuration. ``` -------------------------------- ### Docker-Oriented Build Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Builds the project with the 'docker' profile, which skips tests and Javadoc generation, and disables formatting. This is intended for creating Docker images. ```bash ./mvnw -Pdocker package ``` -------------------------------- ### Run CLI from Source Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Executes the OpenAPI Diff CLI tool directly from the built shaded JAR. Ensure the JAR name includes the version and '-all' classifier. ```bash java -jar cli/target/openapi-diff-cli-*-all.jar --help ``` -------------------------------- ### Load OpenAPI Diff configuration from YAML file Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/configuration.md Demonstrates how to load OpenAPI Diff configuration properties from a YAML file. This allows for centralized management of compatibility checks. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("config.yaml")) .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations("old.json", "new.json", null, options); if (diff.isCoreChanged().isIncompatible()) { System.out.println("Breaking changes detected"); System.exit(1); } ``` -------------------------------- ### Static Import for AssertJ Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Demonstrates the preferred way to statically import AssertJ assertion methods in test classes for cleaner test code. ```java import static org.assertj.core.api.Assertions.assertThat; ``` -------------------------------- ### Auto-Format Java Sources Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Applies automatic formatting to Java source files using the Coveo fmt-maven-plugin. This ensures consistent code style across the project. ```bash ./mvnw com.coveo:fmt-maven-plugin:format ``` -------------------------------- ### Load Configuration from YAML File Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Load OpenAPI diffing options from a YAML configuration file. This allows disabling specific backward-incompatibility checks. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("config.yaml")) .build(); ``` -------------------------------- ### Checking Backward Incompatibility with Configuration Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Demonstrates the pattern for checking backward incompatibility using a specific configuration property. The `enabled` method on `BackwardIncompatibleProp` checks the configuration context. ```java public enum BackwardIncompatibleProp { REQUEST_PARAMS_INCREASED("incompatible.request.params.increased", true), // ... public boolean enabled(Configuration cfg, Object... formatArgs) { String propName = isEmpty(formatArgs) ? propertyName : String.format(propertyName, formatArgs); return cfg.getBoolean(propName, enabledByDefault); } } // In comparison code: if (REQUEST_PARAMS_INCREASED.enabled(context)) { return DiffResult.INCOMPATIBLE; } ``` -------------------------------- ### OpenAPI Comparison Methods Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/INDEX.md Use these static methods to initiate a comparison between two OpenAPI specifications. They support various input sources like URLs, files, or raw content. ```java OpenApiCompare.fromLocations(oldUrl, newUrl) ``` ```java OpenApiCompare.fromFiles(oldFile, newFile) ``` ```java OpenApiCompare.fromContents(oldContent, newContent) ``` ```java OpenApiCompare.fromSpecifications(oldSpec, newSpec) ``` -------------------------------- ### Using JsonRender for Compact Output Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md For large APIs, use JsonRender for the most compact output format, which is efficient in terms of size. ```java Render renderer = new JsonRender(); // Most compact output ``` -------------------------------- ### Core References - Configuration Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Provides a comprehensive reference for all backward incompatibility check properties, organized by category, including default values, YAML format, and precedence rules. ```APIDOC ## Core References - Configuration ### Description Detailed reference for all configuration options related to backward incompatibility checks. ### Configuration Options - Over 50 properties organized by category (e.g., Endpoint-level checks, Request body, Parameters, Schema constraints, Response content, Security schemes). - Default values are provided for each option. ### Configuration Methods - **YAML Configuration File**: Specifies the format and provides examples for using YAML files. - **Property Overrides**: Details how to override configuration properties programmatically or via system properties. - **Precedence Rules**: Explains the order in which different configuration sources are applied. ``` -------------------------------- ### Compare Local OpenAPI Files Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/UsagePatterns.md Compares two local OpenAPI specification files. Requires the `OpenApiCompare` class and `ChangedOpenApi` model. Checks for breaking and compatible changes. ```java import org.openapitools.openapidiff.core.OpenApiCompare; import org.openapitools.openapidiff.core.model.ChangedOpenApi; // Compare two local specification files ChangedOpenApi diff = OpenApiCompare.fromLocations( "specs/api-v1.json", "specs/api-v2.json" ); // Check result if (diff.isCoreChanged().isIncompatible()) { System.out.println("Breaking changes detected!"); } else if (diff.isCoreChanged().isCompatible()) { System.out.println("Changes are backward compatible"); } ``` -------------------------------- ### Error Handling Pattern with OpenAPI Diff Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/errors.md Demonstrates a comprehensive error handling strategy for loading, analyzing, and rendering OpenAPI specifications using OpenAPI Compare. It includes specific catches for RuntimeException, IOException, and other potential issues, with guidance on accessing the root cause. ```java try { // 1. Load specifications ChangedOpenApi diff = OpenApiCompare.fromLocations( oldSpecUrl, newSpecUrl, auths, options ); // 2. Analyze results if (diff.isCoreChanged().isIncompatible()) { System.err.println("API changes break backward compatibility"); return 1; } // 3. Render output Render renderer = new MarkdownRender(); try (FileWriter fw = new FileWriter("diff.md"); OutputStreamWriter osw = new OutputStreamWriter(fw)) { renderer.render(diff, osw); } catch (IOException e) { System.err.println("I/O error writing output: " + e.getMessage()); return 2; } } catch (RuntimeException e) { if (e.getCause() instanceof IOException) { System.err.println("Network or file I/O error: " + e.getCause()); } else if (e.getMessage().contains("Cannot read")) { System.err.println("Invalid OpenAPI specification: " + e.getMessage()); } else { System.err.println("Unexpected error: " + e.getMessage()); e.printStackTrace(); } return 1; } ``` -------------------------------- ### Validation Pattern for OpenAPI Diff Inputs Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/errors.md Illustrates essential input validation steps before processing OpenAPI specifications. This includes checking for the existence of input files, ensuring the output directory can be created, and validating configuration settings. ```java // Validate input files exist if (!oldFile.exists()) { System.err.println("Old spec file not found: " + oldFile); System.exit(1); } if (!newFile.exists()) { System.err.println("New spec file not found: " + newFile); System.exit(1); } // Validate output directory File outputDir = new File("output"); if (!outputDir.exists()) { if (!outputDir.mkdirs()) { System.err.println("Cannot create output directory"); System.exit(1); } } // Validate configuration try { OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configYaml(new File("config.yaml")) .build(); } catch (IllegalArgumentException e) { System.err.println("Invalid configuration: " + e.getMessage()); System.exit(1); } ``` -------------------------------- ### Customize OpenAPI Comparison Rules Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Configure the comparison process by setting specific properties or providing a custom YAML configuration file. This allows fine-tuning the detection of changes based on project needs. ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configProperty("incompatible.openapi.endpoints.decreased", "false") .configYaml(new File("config.yaml")) .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations("old.json", "new.json", null, options); ``` -------------------------------- ### DiffContext Methods for Comparison Scope Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Demonstrates methods on the DiffContext object used to create specialized contexts for specific comparison scopes, such as by HTTP method, request/response, or required fields. ```java // Create context for specific comparison scope public DiffContext copyWithMethod(PathItem.HttpMethod method) public DiffContext copyWithRequired(boolean required) public DiffContext copyAsRequest() public DiffContext copyAsResponse() public DiffContext copyWithLeftRightUrls(String leftUrl, String rightUrl) ``` -------------------------------- ### configYaml() - Load configuration from YAML Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Loads configuration properties from a specified YAML file. This method is part of the builder pattern for configuring OpenApiDiffOptions. ```APIDOC ## configYaml() Load configuration properties from a YAML file. ```java public Builder configYaml(File file) ``` ### Parameters #### Path Parameters - **file** (File) - Required - YAML configuration file **Return**: `Builder` — For method chaining **Throws**: `IllegalArgumentException` if file cannot be read or parsed **Example**: ```java Builder builder = OpenApiDiffOptions.builder(); builder.configYaml(new File("/etc/openapi-diff/config.yaml")); OpenApiDiffOptions options = builder.build(); ``` **Configuration file format** (YAML): ```yaml incompatible.openapi.endpoints.decreased: false incompatible.request.params.decreased: false incompatible.request.required.increased: true incompatible.response.enum.increased: true ``` ``` -------------------------------- ### CI-Style Build with Verbose Output Source: https://github.com/openapitools/openapi-diff/blob/master/AGENTS.md Runs a build with enhanced output, batch mode, and skips plugin group resolution, including Jacoco report generation. This command is close to the CI environment. ```bash ./mvnw -V -B -ntp -ff verify jacoco:report ``` -------------------------------- ### configProperty() - Set a single configuration property Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiDiffOptions.md Sets a single configuration property as a key-value pair. This method can be called multiple times, with later calls overriding earlier ones. It's part of the builder pattern. ```APIDOC ## configProperty() Set a single configuration property as key-value pair. Can be called multiple times. Later calls override earlier ones. ```java public Builder configProperty(String propKey, String propVal) ``` ### Parameters #### Path Parameters - **propKey** (String) - Required - Configuration property key (e.g., "incompatible.openapi.endpoints.decreased") - **propVal** (String) - Required - Property value as string **Return**: `Builder` — For method chaining **Example**: ```java OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configProperty("incompatible.openapi.endpoints.decreased", "false") .configProperty("incompatible.request.params.decreased", "false") .configProperty("incompatible.response.enum.increased", "true") .build(); ``` ``` -------------------------------- ### Using Custom PathMatcher for Performance Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Employ a custom PathMatcher for known URL patterns to potentially speed up path comparisons in large APIs. ```java // Faster matcher for your specific URL structure OpenApiDiffOptions options = OpenApiDiffOptions.builder() .pathMatcher(customMatcher) .build(); ``` -------------------------------- ### OpenApiCompare Methods Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Provides methods for comparing two OpenAPI specifications from various sources like locations, files, or content. It serves as the main entry point for initiating comparisons. ```APIDOC ## OpenApiCompare ### Description Main entry point for comparing OpenAPI specifications. Supports loading specifications from locations, files, contents, or existing specification objects, with options for authorization. ### Methods - `fromLocations(String oldSpecLocation, String newSpecLocation)` - `fromFiles(File oldSpecFile, File newSpecFile)` - `fromContents(String oldSpecContent, String newSpecContent)` - `fromSpecifications(OpenAPI oldSpec, OpenAPI newSpec)` ### Usage ```java import org.openapitools.openapidiff.core.OpenApiCompare; import org.openapitools.openapidiff.core.model.ChangedOpenApi; ChangedOpenApi diff = OpenApiCompare.fromLocations("specs/api-v1.json", "specs/api-v2.json"); ``` ``` -------------------------------- ### Rendering OpenAPI Diff Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/INDEX.md Use the `Render` class to generate a human-readable output of the OpenAPI differences. Specify the diff object and a writer for the output. ```java Render.render(diff, writer) ``` -------------------------------- ### Legacy String-Based Output Rendering (Deprecated) Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/AdvancedTopics.md Illustrates the legacy, deprecated method of rendering a diff to a String. This approach can lead to OutOfMemoryException for large API diffs as it loads the entire diff into memory. ```java // Deprecated - can load entire diff into memory String jsonString = renderer.render(diff); ``` -------------------------------- ### Output Rendering Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/README.md Provides an interface and implementations for rendering comparison results in various formats such as JSON, Markdown, HTML, AsciiDoc, and plain text to an output stream. ```APIDOC ## OutputRendering ### Description Interface for rendering the results of an OpenAPI comparison into different formats. Implementations are provided for JSON, Markdown, HTML, AsciiDoc, and console output. ### Renderers - `JsonRender`: Renders the diff as JSON. - `MarkdownRender`: Renders the diff as Markdown. - `HtmlRender`: Renders the diff as HTML. - `AsciidocRender`: Renders the diff as AsciiDoc. - `ConsoleRender`: Renders the diff to the console. ### Usage ```java import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.JsonRender; import java.io.OutputStreamWriter; // Assuming 'diff' is a ChangedOpenApi object new JsonRender().render(diff, new OutputStreamWriter(System.out)); ``` ### Deprecated Method - A deprecated String-based rendering method exists but is not recommended for use. ``` -------------------------------- ### Run OpenAPI-diff using Docker Source: https://github.com/openapitools/openapi-diff/blob/master/README.md Execute OpenAPI-diff within a Docker container, mounting local specification files. This command compares two OpenAPI files mounted into the container. ```bash docker run --rm -t \ -v $(pwd)/core/src/test/resources:/specs:ro \ openapitools/openapi-diff:latest /specs/path_1.yaml /specs/path_2.yaml ``` -------------------------------- ### ConsoleRender Constructor Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OutputRendering.md Instantiates a new ConsoleRender object. ```java public ConsoleRender() ``` -------------------------------- ### Compare Remote OpenAPI Specifications Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/UsagePatterns.md Compares two OpenAPI specification files fetched from HTTP URLs. Uses the `OpenApiCompare.fromLocations` method. ```java // Compare from HTTP URLs ChangedOpenApi diff = OpenApiCompare.fromLocations( "https://api.example.com/v1/openapi.json", "https://api.example.com/v2/openapi.json" ); ``` -------------------------------- ### Compare OpenAPI Specs from Locations Source: https://github.com/openapitools/openapi-diff/blob/master/_autodocs/api-reference/OpenApiCompare.md Compares two OpenAPI specifications by providing their paths or URLs. Supports authorization values and custom comparison options. ```java public static ChangedOpenApi fromLocations(String oldLocation, String newLocation) public static ChangedOpenApi fromLocations(String oldLocation, String newLocation, List auths) public static ChangedOpenApi fromLocations(String oldLocation, String newLocation, List auths, OpenApiDiffOptions options) ``` ```java // Compare two remote specifications ChangedOpenApi diff = OpenApiCompare.fromLocations( "https://api.example.com/openapi.v1.json", "https://api.example.com/openapi.v2.json" ); // Compare with authorization headers List auths = new ArrayList<>(); auths.add(new AuthorizationValue("Authorization", "Bearer token123", "header")); ChangedOpenApi diff = OpenApiCompare.fromLocations( "https://api.example.com/spec", "https://api.example.com/spec-new", auths ); // Compare with custom options OpenApiDiffOptions options = OpenApiDiffOptions.builder() .configProperty("incompatible.openapi.endpoints.decreased", "false") .build(); ChangedOpenApi diff = OpenApiCompare.fromLocations( "old-spec.json", "new-spec.json", null, options ); ```