Search code examples
c#parsingyamlopenapiopenapi.net

How to parse extensions of yaml in OpenApi.NET into .NET classes?


I need to write ExtensionParsers for OpenApi.NET, so that when I parse a yaml document, the extension properties (properties named x-something) are parsed into the corresponding C# classes that I wrote instead of being parsed generally into OpenApiObject.

So for example, when I use OpenApi.NET to parse the following yaml document:

openapi: 3.0.2
info:
  title: 'My interface'
  version: '1.0'
servers:
  - url: https://www.example.com
paths:
  "/student":
    get:
      parameters:
      - name: school
        in: query
        schema:
          type: string
      x-setting:
        name: 'Hello world'
        number: 312
        device: mobile
      responses:
        "200":
          description: Successful
          headers:
            Content-Type:
              schema:
                type: string
          content:
            application/json:
              schema:
                type: string

the parameter object is parsed to a C# object of type OpenApiParameter, name is of type string, In is an enum of type ParameterLocation and schema is of type OpenApiSchema.

But x-setting is parsed to a C# object of type OpenApiObject, name is parsed as OpenApiString, number is parsed as OpenApiInteger and device as OpenApiString.

But as I already have the following c# class:

class Setting
    {
        string Name;
        int Number;
        Device Device;
    }

I want it to be parsed to a C# object of type Setting, name as string, number as integer and device as an enum of type Device. Exactly like the parameter object.

It is mentioned here that this can be done using the property ExtensionParsers. But it is not clear how.

There are no docs and the explanation in comments in code is not so good. So could someone help on this?

Many thanks.


Solution

  • You need to provide an extension parser to do the transformation from the OpenApiObject to the native C# class. e.g.

     var settings = new OpenApiReaderSettings()
                {
                    ExtensionParsers = { { "x-foo", (a,v) => {
                            var fooNode = (OpenApiObject)a;
                            return new FooExtension() {
                                  Bar = (fooNode["bar"] as OpenApiString)?.Value,
                                  Baz = (fooNode["baz"] as OpenApiString)?.Value
                            };
                    } } }
                };
    

    https://github.com/microsoft/OpenAPI.NET/blob/3aeeef600d19e4ecfdf0d116725658b1c496eba0/test/Microsoft.OpenApi.Readers.Tests/TestCustomExtension.cs#L29

    Sorry there are not docs, I unfortunately just have not had time.