Generating Swagger YAML for Asp.Net Core API

I am generating swagger YAML for an Asp.Net core API project. Recently, I have added an option to download the swagger document in YAML format for one of my Asp.net core APIs. When you add swagger to your asp.net core project, by default implementation you can download swagger.json. However, here I am adding another swagger format to download.

In one of my previous post I demonstrate one way to add Swagger in Asp.Net core API including versioning. You may find the name of the nuget packages and steps to add swagger to your asp.net API project. I am evolving the repository to include YAML implementation

Nuget Packages

I am using YamlDotNet.NetCore to generate yaml file.

At the same time, I have also used Swashbuckle.AspNetCore to add swagger and Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer for versioning

IDocumentFilter

To generate YAML from the xml file, I have added an implementation of IDocumentFilter. It has only one method Apply. I have used YamlDotNet serializer to generate YAML. I have generated the Yaml file into the wwwroot folder as this is the only place available to access any static file through URI

public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) {
    var builder = new SerializerBuilder();
    builder.WithNamingConvention(new CamelCaseNamingConvention());
    builder.WithTypeInspector(innerInspector => new PropertiesIgnoreTypeInspector(innerInspector));

    var serializer = builder.Build();

    using (var writer = new StringWriter()) {
        serializer.Serialize(writer, swaggerDoc);

        var file = Path.Combine(hostingEnvironment.WebRootPath, "swagger.yaml");
        using (var stream = new StreamWriter(file)) {
            var result = writer.ToString();
            stream
                .WriteLine(result
                    .Replace("2.0", "\"2.0\"", StringComparison.OrdinalIgnoreCase)
                    .Replace("ref:", "$ref:", StringComparison.OrdinalIgnoreCase));
        }
    }
}

hostingEnvironment has been injected to the YamlDocumentFilter class. And also, I have created the PropertiesIgnoreTypeInspector class which is inherited from TypeInspectorSkeleton. As a matter of fact, GetProperties method has been overridden to ignore extensions and operation-id

private class PropertiesIgnoreTypeInspector : TypeInspectorSkeleton {
    private readonly ITypeInspector typeInspector;
    public PropertiesIgnoreTypeInspector(ITypeInspector typeInspector) {
        this.typeInspector = typeInspector;
    }
    public override IEnumerable<IPropertyDescriptor> GetProperties(Type type, object container) {
        return typeInspector.GetProperties(type, container).Where(p => p.Name != "extensions" && p.Name != "operation-id");
    }
}

Certainly, I need to add this implementation YamlDocumentFilter to the swagger services. I add this to SwaggerGenOptions

options.DocumentFilter<YamlDocumentFilter>();

Downloading YAML

In fact, I have added few lines to Configure method of Startup class so that the user can download the generated YAML file from swagger UI.

app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions {
    ServeUnknownFileTypes = true,
    DefaultContentType = "application/yaml"
});

Github Repo

I have added YAML support to one of API which you may find it here. Please check the commit 22690cd7 to find the changes required to generate swagger.yaml.

Using YAML

You can download the YAML file and try it on editor.swagger.io. There you can download client sdk or server sdk in many languages.

References

1 thought on “Generating Swagger YAML for Asp.Net Core API”

I would like to hear your thoughts