Giter VIP home page Giter VIP logo

openapi.net's Introduction

Category overview screenshot

OpenAPI.NET

Package Nuget
Models and Writers nuget
Readers nuget
Hidi nuget

The OpenAPI.NET SDK contains a useful object model for OpenAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model.

See more information on the OpenAPI specification and its history here: OpenAPI Initiative

Project Objectives

  • Provide a single shared object model in .NET for OpenAPI descriptions.
  • Include the most primitive Reader for ingesting OpenAPI JSON and YAML documents in both V2 and V3 formats.
  • Provide OpenAPI description writers for both V2 and V3 specification formats.
  • Enable developers to create Readers that translate different data formats into OpenAPI descriptions.

Installation

Processors

The OpenAPI.NET project holds the base object model for representing OpenAPI documents as .NET objects. Some developers have found the need to write processors that convert other data formats into this OpenAPI.NET object model. We'd like to curate that list of processors in this section of the readme.

The base JSON and YAML processors are built into this project. Below is the list of the other supported processor projects.

  • C# Comment / Annotation Processor : Converts standard .NET annotations ( /// comments ) emitted from your build (MSBuild.exe) into OpenAPI.NET document object.

  • OData CSDL Processor : Converts the XML representation of the Entity Data Model (EDM) describing an OData Service into OpenAPI.NET document object.

Example Usage

Creating an OpenAPI Document

var document = new OpenApiDocument
{
    Info = new OpenApiInfo
    {
        Version = "1.0.0",
        Title = "Swagger Petstore (Simple)",
    },
    Servers = new List<OpenApiServer>
    {
        new OpenApiServer { Url = "http://petstore.swagger.io/api" }
    },
    Paths = new OpenApiPaths
    {
        ["/pets"] = new OpenApiPathItem
        {
            Operations = new Dictionary<OperationType, OpenApiOperation>
            {
                [OperationType.Get] = new OpenApiOperation
                {
                    Description = "Returns all pets from the system that the user has access to",
                    Responses = new OpenApiResponses
                    {
                        ["200"] = new OpenApiResponse
                        {
                            Description = "OK"
                        }
                    }
                }
            }
        }
    }
};

Reading and writing an OpenAPI description

var httpClient = new HttpClient
{
    BaseAddress = new Uri("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/")
};

var stream = await httpClient.GetStreamAsync("master/examples/v3.0/petstore.yaml");

// Read V3 as YAML
var openApiDocument = new OpenApiStreamReader().Read(stream, out var diagnostic);

// Write V2 as JSON
var outputString = openApiDocument.Serialize(OpenApiSpecVersion.OpenApi2_0, OpenApiFormat.Json);

Validating/Testing OpenAPI descriptions

In order to test the validity of an OpenApi document, we avail the following tools:

  • Microsoft.OpenApi.Hidi

    A commandline tool for validating and transforming OpenAPI descriptions. Installation guidelines and documentation

  • Microsoft.OpenApi.Workbench

    A workbench tool consisting of a GUI where you can test and convert OpenAPI descriptions in both JSON and YAML from v2-->v3 and vice versa.

    Installation guidelines:

    1. Clone the repo locally by running this command: git clone https://github.com/microsoft/OpenAPI.NET.git
    2. Open the solution file (.sln) in the root of the project with Visual Studio
    3. Navigate to the src/Microsoft.OpenApi.Workbench directory and set it as the startup project
    4. Run the project and you'll see a GUI pop up resembling the one below:
    1. Copy and paste your OpenAPI descriptions in the Input Content window or paste the path to the descriptions file in the Input File textbox and click on Convert to render the results.

Build Status

master
Build status

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

To provide feedback and ask questions you can use Stack Overflow with the OpenAPI.NET tag or use the OpenAPI.NET Slack channel which you can join by registering for the HTTP APIs team at http://slack.httpapis.com.

openapi.net's People

Contributors

aleks-ivanov avatar andrewrissing avatar andrueastman avatar baywet avatar bdebaere avatar cumpsd avatar danielmbaluka avatar darrelmiller avatar dependabot[bot] avatar elize-vdr avatar ericatmsft avatar ericwilson-blueprism avatar foriequal0 avatar irvinesunday avatar maggiekimani1 avatar michaelmainer avatar millicentachieng avatar nulltoken avatar peombwa avatar perthcharern avatar peteraritchie avatar ravennasoftware avatar senthilkumarmohan avatar shwetap05 avatar simon-pearson-lmk avatar simoncropp avatar tinaliu02 avatar vitaliykurokhtin avatar xuzhg avatar zengin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openapi.net's Issues

Clean the build warning

We have some build warning like:

warning CS1591: Missing XML comment for publicly visible type or member 'OpenApiConstants.OpenApi'
1>Models\OpenApiConstants.cs(15,29,15,33): warning CS1591: Missing XML comment for publicly visible type or member 'OpenApiConstants.Info'
1>Models\OpenApiConstants.cs(17,29,17,34): warning CS1591: Missing XML comment for publicly visible type or member 'OpenApiConstants.Title'
1>Models\OpenApiConstants.cs(19,29,19,33): warning CS1591: Missing XML comment for publicly visible type or member 'OpenApiConstants.Type'
1>Models\OpenApiConstants.cs(21,29,21,35): warning CS1591: Missing XML comment for publicly visible type or member 'OpenApiConstants.Format'

///

I will help to add the missing XML.

Do we need to release fixtures?

@darrelmiller I don't think we should release the fixtures folder with this repo. It has more to do with the spec itself. If we need some of these docs in the unit tests, we can include them directly there. What do you think?

Region vs partial classes

@xuzhg @darrelmiller What do you guys think about changing the Deserializer from one big file with multiple regions into multiple partial classes (based on the model)?

One advantage I see is that now the reader files can be easily mapped 1-to-1 to the model, and it will be clearer to the contributor which file(s) to touch when a model is changed.

Make PathItem a referenceable object

Path items can be referenced but they are a special case for a couple of reasons.
a) they don't have a home in components
b) the reference doesn't work like a normal JSON reference because peer properties in the target path item are not ignored, they are merged.

Create interface for reader

@xuzhg @darrelmiller

Is one of you working on this already? If not, I can take a stab at this.

Based on our last discussion, we will have something along the line of:

  • An interface class (possibly with generic template)

  • Load/Parse/Read method

@darrelmiller Darrel, you mentioned in the call that we can base the methods out of XDocument. I looked through that but it seems like most other methods (Write, ToString, ReplaceNode, Add, etc.) don't really fit in out concept of the reader. I'd say we only have one "read" method here. I think Read seems like a good name for me (instead of Load/Parse) since we name the projects Readers - do you guys agree/disagree?

Reference in Discriminator.Mapping

Discriminator.Mapping can contain string that refers to schema reference. Currently it's just string right now. We might be able to switch this over to something that leverages our Reference implementation. (similar to tag/security scheme)

Serialize an empty OpenApiDocument throw null reference exception.

static void Main(string[] args)
{
      OpenApiDocument document = new OpenApiDocument();
      Console.WriteLine(document.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0_0));
}

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.OpenApi.Models.OpenApiDocument.SerializeAsV3(IOpenApiWriter writer) at Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions.Serialize[T](T element, IOpenApiWriter writer, OpenApiSpecVersion specVersion) at Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions.Serialize[T](T element, Stream stream, OpenApiSpecVersion specVersion, OpenApiFormat format) at Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions.Serialize[T](T element, OpenApiSpecVersion specVersion, OpenApiFormat format) at Microsoft.OpenApi.Extensions.OpenApiSerializableExtensions.SerializeAsJson[T](T element, OpenApiSpecVersion specVersion) at OpenApiTest.Program.Main(String[] args) in E:\study\OpenApiTest\OpenApiTest\Program.cs:line 17 Press any key to continue . . .

Bugs in YamlWriter

String handling

https://stackoverflow.com/questions/19109912/do-i-need-quotes-for-strings-in-yaml

For example,

If the string "10" is the input, WriteValue("10") should yield '10' (with single quote) to signify that this is indeed a string. Otherwise, this 10 can be interpreted as a number.

Empty object inside the document

{} can be used for empty object. Current implementation only shows empty space, which is not correct.

Empty array inside the document

Add --- in the beginning of file

More specific check for the reading content

For example:

When we read the response, Can we make sure the response status codes is HTTP status code (3-digit-number starting with 1, 2, 3, 4, 5 or the range definition allowed: 1XX, 2XX, 3XX, 4XX, 5XX)

[Discuss] Design & implement Any type in Open API

Please share your thoughts:

Open API spec says:

Field Pattern Type Description
^x- Any Allows extensions to the OpenAPI Schema. The field name MUST begin with x-, for example, x-internal-id. The value can be null, a primitive, an array or an object. Can have any valid JSON format value.

So, the Any type could be:

  1. Null,
  2. Primitive
  3. Array
  4. Object

While, Open API spec says:

Common Name type format Comments
integer integer int32 signed 32 bits
long integer int64 signed 64 bits
float number float  
double number double  
string string    
byte string byte base64 encoded characters
binary string binary any sequence of octets
boolean boolean    
date string date As defined by full-date - RFC3339
dateTime string date-time As defined by date-time - RFC3339
password string password A hint to UIs to obscure input.

So, I think I want to use the PR #15: to represent the structure.

Improving unit tests

Unit tests we have are not sufficient, and the way each test is written is inconsistent with one another.

Reference loading, the async challenge

Currently the DOM is designed so that strong types such as OpenAPISchema can be marked as a reference. This enables the model to know that these types are explicitly being re-used from the components collection.

Currently references are loaded immediately upon parsing a document so that references are always represented by the correct types and those instances contain all the referenced data. This is convenient when working with the object model as referenced objects and non-referenced can be interacted with transparently.

When it comes to loading references from external documents, this approach presents some challenges:

  • Loading from an external document should be async. Transparently loading external references would push async all the way through the model to the main load even if there were no external references in a particular document.
  • What if someone wanted to process a set of documents that contained external references but didn't need to load them to perform the updates? Should we not support loading documents without dereferencing external references? If so how should those references be represented in the model?
  • How do you construct a DOM with an external reference? Do you need an instance of the external DOM to do it?

It feels like we cannot get away from having a model type that can have a OpenApiReference instance but be in an "unresolved" state.

   var unresolvedSchema = new OpenApiSchema {
      Reference = new OpenApiReference("common.json#/components/schema/cat")
   };

Does this mean that we need to put a guard clause in every get accessor that prevents reading the regular properties? How do we construct a reusable object to be added to Components? Do we create it without the reference and then when adding it to the components collection a reference gets added automatically?

Or do we change the approach to the way we deal with references and instead of using the same object in the components collection and the reference to it, we create a new SchemaReference type that does aggregation and delegation.

e.g.

   content.Schema = new SchemaReference("cat",doc.Components.Schemas["cat"]);

This would require the SchemaReference to re-surface the entire Schema API. This would provide a nice place to put the guard against derefencing an unresolved reference, but it would also mean either creating an ISchema interface, or deriving from Schema and making all the properties virtual. Both of which are high maintenance approaches.

Equality issue with SecurityRequirement.Schemes

SecurityScheme object is used as dictionary key in SecurityRequirement.Schemes.

We need to do one of the following:

1. Implement GetHashCode / Equals in SecurityScheme and ALL the downstream classes
2. Implement SecuritySchemeComparer : IEqualityComparer and use that to construct the dictionary. This is an ad-hoc comparer and all the dive-down equality comparisons will only be present in this class.

I personally prefer 1, but it might make the models a little larger and cluttered. I'll send out a PR to see what you guys think.

OpenApiAny vs primitive type inconsistency

@darrelmiller @xuzhg

We have been using an OpenApiAny type (e.g. OpenApiString, OpenApiDouble) to represent strings, numbers, arrays, etc. in the property that can be of type OpenApiAny.

However, in other properties of a normal object, we simply use the C# primitive types like string, int.

This is semantically inconsistent in my opinion. An "Any" type in the spec simply means it can be anything. If we use OpenApiString to mean a string inside that "Any" type, we should exclusively use OpenApiString everywhere. If we use the C# primitive, then we should use the C# primitive everywhere.

Using OpenApiAny allows us to control the type to match what JSON schema allows and add some types recognized by the spec like Password, but will be a pain for our customers if they need to assign values with OpenApiAny everywhere since it's less intuitive to do so compared to just C# primitives.

Fluent Assertions for xUnit

I am a big fan of the Fluent Assertions framework http://fluentassertions.com/, which integrates well with xUnit.

It gets rid of the Assert.XXX syntax and use a more human-readable actual.Should().Be().EqualTo(expected) syntax. It also provides out-of-the-box support for deep object comparison. The error message pinpoints where exactly two objects are different.

I don't see a downside except from an extra dependency. This project is available on NuGet and widely used though, so I don't think that's too big of an issue either.

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.