Search code examples
c#.net-coreopenapijsonschemanswag

Generating valid schema for generic type in OpenAPI v3 with NSwag


I am trying to generate a valid OpenApiDocument using NSwag but fail when it comes to generate schemas the way they should be. I am currently adding schemas for my types globally like this:

var type = ...; // e.g. List<User>

var settings = new SystemTextJsonSchemaGeneratorSettings()
{
    SchemaType = SchemaType.OpenApi3,
};

var schema = JsonSchema.FromType(type, settings);

document.Components.Schemas.Add(key, schema);

This produces

    "components": {
        "schemas": {
            "ListOfUser": {
                "title": "ListOfUser",
                "type": "array",
                "items": {
                    "$ref": "#/components/schemas/ListOfUser/definitions/User"
                },
                "definitions": {
                    "User": {
                        "type": "object",
                        "additionalProperties": false,
                        "properties": {
                            "ID": {
                                "type": "integer",
                                "format": "int32"
                            },
                            "Name": {
                                "type": "string"
                            }
                        }
                    }
                }
            }
        }
    },

Swagger Editor fails to validate this definition because

Structural error at components.schemas.ListOfUser
should NOT have additional properties
additionalProperty: definitions
Jump to line 30

As far as I understand the specc there should be two entries, one for the list and one for the type itself, but I fail to see how to generate this with NSwag.

Do I need to create the two entries myself and manually adjust the list entry to make this work?


Solution

  • You can use the OpenApiSchemaResolver that will act as a registry to find already registered schemas:

    var settings = new NewtonsoftJsonSchemaGeneratorSettings()
    {
        SchemaType = SchemaType.OpenApi3,
        AllowReferencesWithProperties = true
    };
    
    var generator = new JsonSchemaGenerator(settings);
    var resolver = new OpenApiSchemaResolver(document, settings);
    
    var schema = generator.GenerateWithReferenceAndNullability<JsonSchema>(type.ToContextualType(), false, resolver);
    

    This will also generate a different style of schema definitions:

        "components": {
            "schemas": {
                "User": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                        "ID": {
                            "type": "integer",
                            "format": "int32"
                        },
                        "Name": {
                            "type": "string"
                        }
                    }
                }
            }
        },