Search code examples
c#asp.net-coreswaggeropenapiswashbuckle.aspnetcore

ASP.NET.core swagger generate swagger file programatically


I have an asp.net core web api that I created from the wizard - and it's generated code like this:

        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.
            builder.Services.AddAuthorization();

            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
    ...

And if I run it, I get a swagger url, and I can go to

https://localhost:7100/swagger/v1/swagger.yaml

and get a yaml file... that's all good.

The Question

However, I need that yaml file in the CI/CD process for various reasons, so I want to get it dynamically after building, but starting a web server, calling it, and bringing it down has a lot of ways it can go wrong. What I'd like to do is just make a command line option to get the swagger file that never starts something listening on http. so I can just run "dotnet run myApi generate_swagger_yaml >swagger.yaml" Something like:

public static void Main(string[] args)
{
   if (args[0] == "generate_swagger_yaml")
   {
        var yamlFile = ....somehow get the swagger yaml file...
        Console.Writeline( yamlfile );
        return 0;
   }
   ...

but I can't figure out how to do it.


Solution

  • Since my last answer, I've had to experiment more with Swashbuckle and Swagger generation and I've found the actual answer to your original question.

    Once you create your builder:

    var app = builder.Build();
    

    You need to fetch the IServiceProvider from it and use it to resolve an instance of ISwaggerProvider. With this, you can get the swagger document and render it to Json or Yaml.

    var swaggerProvider = app.Services.GetRequiredService<ISwaggerProvider>();
    var swagger = swaggerProvider.GetSwagger("v1");
    var stringWriter = new StringWriter();
    swagger.SerializeAsV3(new OpenApiYamlWriter(stringWriter));
    var swaggerYaml = stringWriter.ToString();
    Console.WriteLine(swaggerYaml);
    

    Where "v1" should be the default name of your swagger doc which you can specify when setting it up like so:

    services.AddSwaggerGen(c =>
    {
      c.SwaggerDoc("v7", null);
    });