3
votes

I am trying to create a dynamic rest api that uses Swagger for documentation in .NetCore (using Swashbuckle.AspNetCore). Dynamic in the sense that there is only 1 controller with 1 possible response to begin with, but a user can add "end points" by POSTing to the service, which then later the controller can translate the new routes to respond accordingly

In order to do this, I need to be able to access and change the swagger.json file as well as have the UI change to reflect the changes - is this possible? if so how?

Note: I know I can access and see the swagger doc by navigating to /{documentname}/swagger.json but this does not allow me to change it

1
Sounds like Swashbuckle Swagger is the wrong tool for you and you should create your own swagger schema (hard), maybe even use a static one created by programs like editor.swagger.io/# or generate a swagger.json from YAML. Swashbuckle uses your controllers, routes and models to generate the definitionTseng

1 Answers

3
votes

You can extend, filter and customize the schema with custom filters: https://github.com/domaindrivendev/Swashbuckle.AspNetCore#extend-generator-with-operation-schema--document-filters

I did use that for decorating more header-fields to a each request (like authorization header). I'm not sure, if it's gonna work with whole endpoints. But maybe it's worth a try.


Update (Edited)
Here is a sample IDocumentFilter that adds whole endpoints:

private class DocumentFilterAddFakes : IDocumentFilter
{
    private PathItem FakePathItem(int i)
    {
        var x = new PathItem();
        x.Get = new Operation()
        {
            Tags = new[] { "Fake" },
            OperationId = "Fake_Get" + i.ToString(),
            Consumes = null,
            Produces = new[] { "application/json", "text/json", "application/xml", "text/xml" },
            Parameters = new List<IParameter>()
                    {
                        new NonBodyParameter() // Can also be BodyParameter
                        {
                            Name = "id",
                            @In = "path",
                            Required = true,
                            Type = "integer",
                            Format = "int32",
                            @Default = 8
                        }
                    },
        };
        x.Get.Responses = new Dictionary<string, Response>();
        x.Get.Responses.Add("200", new Response() { Description = "OK", Schema = new Schema() { Type = "string" } });
        return x;
    }

    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
    {
        for (int i = 0; i < 10; i++)
            swaggerDoc.paths.Add("/Fake/" + i  + "/{id}", FakePathItem(i));
    }
}