Giter Club home page Giter Club logo

openapi-comparator's Introduction

Open API Comparator

An OpenAPI tool to compare OpenAPI Specifications.

C# Library

The tool is available as a nuget package, directly usable into your C# application.

To install it run the command:

dotnet add package Criteo.OpenApi.Comparator

Here is an example of how to use the Comparator:

var differences = OpenApiComparator.Compare(
    oldOpenApiSpec,
    newOpenApiSpec
);

Command line tool

The comparator is also available as a command line tool.

To install it, run the command:

dotnet tool install -g Criteo.OpenApi.Comparator.Cli

You can then use the tool through the openapi-compare command:

openapi-compare -o new_oas.json -n old_oas.json -f Json

Available options:

Option Small Required Description
--old -o true Path or URL to old OpenAPI Specification.
--new -n true Path or URL to new OpenAPI Specification.
--outputFormat -f false (Default: Json) Specifies in which format the differences should be displayed. Possible values: Json | Text.
--strict -s false (Default: false) Enable strict mode: breaking changes are errors instead of warnings.
--help -h false Log available options

Comparison rules

Each comparison rule is documented in the documentation section.

OpenAPI version support

Internally, the comparator uses microsoft/OpenAPI.NET which currently supports OpenAPI 2.0 to 3.0.0.

Contributing

Any contribution is more than welcomed. For now, no specific rule must be applied to contribute, just create an Issue or a Pull Request and we'll try to handle it ASAP.

License

OpenApi Comparator is an Open Source software released under the Apache 2.0 license.

Developper guide

Simply use the dotnet cli. For example, to run the tests:

dotnet test

openapi-comparator's People

Contributors

nextfire avatar paulmathon avatar ttembou avatar ouvreboite avatar tibonihoo avatar gricher-criteo avatar

Stargazers

Oleksander avatar  avatar Drew Burlingame avatar Ben Brandt avatar Chris Scheib avatar Utku Görkem Ertürk avatar  avatar Francisco Martín avatar Vladimir Shchur avatar Daniel Vo avatar Joel Dickson avatar Effi avatar guillaume avatar  avatar Andrejs Agejevs avatar Anthony D'Amato avatar Ray avatar Michiel van Oudheusden avatar Adam Setch avatar Marsh Gardiner avatar Maxim Mosin avatar  avatar VERNOU Cédric avatar Its Anas avatar Peter Ritchie avatar

Watchers

 avatar Emmanuel Guérin avatar Gaëlle R. avatar Ishan Gautam avatar  avatar Scott McCord avatar  avatar  avatar

openapi-comparator's Issues

Use of a distant swaggerSpec.json

Hello,

I want to have the possibility to give an URL to download the swagger spec instead of a local file.

I modify the Program.cs of the Criteo.OpenApi.Comparator.Cli like this:

`// Copyright (c) Criteo Technology. All rights reserved.
// Licensed under the Apache 2.0 License. See LICENSE in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.Json;

namespace Criteo.OpenApi.Comparator.Cli
{
///


/// Entry point for OpenAPI Comparator command line tool
///

public static class Program
{
///
/// Must contain --old|-o and --new|-n parameters which are paths to old and new OpenAPI specification
///
public static int Main(string[] args)
{
var parserResult = CommandLine.Parser.Default.ParseArguments(args);

        if (parserResult.Errors.Any())
        {
            return 1;
        }

        var options = parserResult.Value;

        var oldFileFound = TryReadFile(options.OldSpec, out var oldOpenApiSpecification);
        var newFileFound = TryReadFile(options.NewSpec, out var newOpenApiSpecification);

        if (!oldFileFound || !newFileFound)
        {
            Console.WriteLine("Exiting.");
            return 1;
        }

        var differences = OpenApiComparator.Compare(oldOpenApiSpecification, newOpenApiSpecification);

        DisplayOutput(differences, options.OutputFormat);

        return 0;
    }

    private static bool **TryReadFile**(string path, out string fileContent)
    {
        bool readOk = TryReadDistantFile(path, out fileContent);
        if (!readOk)
        {
            TryReadLocalFile(path, out fileContent);
        }
        return readOk;
    }

    private static bool **TryReadDistantFile**(string url, out string fileContent)
    {
        try
        {
            using HttpClient wc = new HttpClient();
            fileContent = wc.GetStringAsync(url).Result;
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine($"File not found for: {url} with the message {e.Message}");
            fileContent = null;
            return false;
        }
    }

    private static bool **TryReadLocalFile**(string path, out string fileContent)
    {
        try
        {
            fileContent = File.ReadAllText(path);
            return true;
        }
        catch (FileNotFoundException f)
        {
            Console.WriteLine($"File not found for: {path} with the message {f.Message}");
            fileContent = null;
            return false;
        }
    }

    private static void DisplayOutput(IEnumerable<ComparisonMessage> differences, OutputFormat outputFormat)
    {
        if (outputFormat == OutputFormat.Json)
        {
            Console.WriteLine(JsonSerializer.Serialize(differences, new JsonSerializerOptions { WriteIndented = true }));
            return;
        }

        foreach (var change in differences)
        {
            if (outputFormat == OutputFormat.Text)
            {
                Console.WriteLine(change);
            }
        }
    }
}

}
`

Could you integrate it?

Thanks

Support for YAML

Would it be possible to add support for YAML? YAML is a common format for OpenAPI specifications, and mostly similar to JSON.

Detect Added and Removed Schema in response

Why

For now, when two schemas are compared, if one of them is null, a misleading ArgumentNullException is thrown during the comparison, which makes the comparison crash without any precise message.

But, if the new OR old schema is null, it actually means that the schema was removed OR added, a Breaking Change should be reported instead of throwing an exception.

What/How

While comparing a new and an old schema:

  • If the new schema is null, but not the old one, the schema is removed, then a RemovedSchema breaking change should be added to the context instead of throwing an ArgumentNullException

  • If the old schema is null, but not the new one, the schema is removed, then an AddedSchema breaking change should be added to the context instead of throwing an ArgumentNullException

  • The AddedSchema comparison rule must be created and properly documented

Acceptance Criteria

  • When two OAS are compared, if a schema is missing in the new OAS, but is present in the old one, Then a RemovedDefinition difference should be returned as part of the comparison result

  • When two OAS are compared, if a schema is missing in the old OAS, but is present in the new one, Then an AddedSchema difference should be returned as part of the comparison result

  • The documentation for the AddedSchema comparison rule should be accessible here.

Error 1043 thrown .AND. Message in the response/output has unicode chars

Example:
"Message": "The optional parameter \u0027\u0027 was added in the new version.",

Full content:
{
"Severity": 1,
"Message": "The optional parameter \u0027\u0027 was added in the new version.",
"OldJsonRef": "#/paths/1subscriptions1{id}~1transactions/get/parameters/0",
"NewJsonRef": "#/paths/1subscriptions1{id}~1transactions/get/parameters/0",
"Id": 1043,
"Code": "AddingOptionalParameter",
"Mode": 0
}

What can I do to have the unicode chars shown in the clear?
Thanks!

[Bug] ComparisonMessage.DocUrl are broken link

The doc url displayed from a comparison message is broken. Example :
https://github.com/Azure/openapi-diff/tree/master/docs/rules/10021.md
https://github.com/Azure/openapi-diff/tree/master/docs/rules/10281.md

To reproduce :

...
var comparator = new OpenApiComparator();
var messages = comparator.Compare(oldFileName, oldOpenApiSpec, newFileName, newOpenApiSpec);
foreach(var message in messages)
{
    Console.WriteLine(message);
}

Output :

..., docurl = https://github.com/Azure/openapi-diff/tree/master/docs/rules/10021.md, mode = Removal
..., docurl = https://github.com/Azure/openapi-diff/tree/master/docs/rules/10281.md, mode = Update
..., docurl = https://github.com/Azure/openapi-diff/tree/master/docs/rules/10281.md, mode = Update

It seems that the problem comes from ComparisonMessage._docBaseUrl. The base doc url is "https://github.com/Azure/openapi-diff/tree/master/docs/rules".

All rules are replicated in this repository, I suggest that comparison message doc url redirect directly to "https://github.com/criteo/openapi-comparator/tree/{version}/documentation/rules".

Do you want some help? I can do the pull request.

Check the change of "required" for properties in Response schema

Hello,

I would like to have the RequiredStatusChange fail for requests and responses, as for now there is no errors for the following contract change:

"MyEntityName": {
      "required": [
        "myProperty1",
-       "myProperty2"
      ],

I checked the implementation, and it bypasses the check for responses:

 if (oldParameter.IsRequired() == newParameter.IsRequired() || context.Direction == DataDirection.Response)
                return;

The description of the rule, "Checks whether an existing property's required status is changed from the previous specification.", doesn't mention anything about this bypass. Furthermore, I believe changing the "required" status in a response is a breaking change as well.

I'll see if I can investigate and push a PR later on.

Message has Unicode characters

I have two simplest files below:

old_openapi.json:
{
"openapi": "3.0.0",
"info": {
"title": "foos",
"version": "1.5"
}
}

new_openapi.json:
{
"openapi": "3.0.0",
"info": {
"title": "foos",
"version": "1.4"
}
}

I run the compare as follows:
openapi-compare -o old_openapi.json -n new_openapi.json

Output:
[
{
"Severity": 2,
"Message": "The new version has a lower value than the old: System.String[] -\u003E System.String[]",
"OldJsonRef": "#/info/version",
"NewJsonRef": "#/info/version",
"Id": 1000,
"Code": "VersionsReversed",
"Mode": 1
}
]

Instead of printing 1.4 and 1.5, it printed some garbled text in the "Message" field.
Could you please let know what's causing it and how to fix it?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.