4

I am currently use Swagger to expose all my endpoints, but these endpoints are currently formatted as: /get/{name}, /put/{name}, where the name can only be those names which I have in database?

Is somehow possible to make swagger expand the general API definition to contain all possible API call one could make, meaning all possible names?

kafka
  • 573
  • 1
  • 11
  • 28
  • Are you using ASP.NET Core? Are you using Swashbuckle? Most likely you will have to hardcode the possible names in an XML comment. I don't see any way to do this excepted using another tool to update your swagger file after reading from the database... – Lucas S. May 19 '20 at 16:11
  • I saw I could do this as a middleware? but how about dbcontext and middleware? – kafka May 19 '20 at 16:17
  • You should be able to add a middleware to the `Configure` method of your `Startup` class. Here you should have access to `IServiceProvider` or other injected dependencies to resolve DbContext (if DbContext has properly been registered in your `ConfigureServices` method). – Lucas S. May 19 '20 at 16:22
  • not quite sure i understand how you want me to this? @LucasS. – kafka May 20 '20 at 18:36
  • See my answer, I tried to explain what I meant in my previous comment. – Lucas S. May 21 '20 at 16:39

1 Answers1

0

I am assuming you are using .NET Core.
I have not tested this solution, but hopefully it is on the right track.

In your Startup class, you are probably registering Swagger in the ConfigureServices method, as well as your database context.

You need to add one line in AddSwaggerGen to register a custom filter.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<YourContext>();

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });

        // Custom filter (could also be a SchemaFilter)
        c.ParameterFilter<CustomParametersFilter>();
    });
}

Here is the CustomParametersFilter class:

public class CustomParametersFilter : IParameterFilter
{
    private readonly YourContext dbContext;

    public CustomParametersFilter(YourContext dbContext)
    {
        // Here you also have access to IServiceProvider or any dependency
        this.dbContext = dbContext;
    }

    public void Apply(IParameter parameter, ParameterFilterContext context)
    {
        if (parameter.Name == "some_name")
        {
            // Use dbContext to retrieve your values
            List<string> validValues;
            // ...

            parameter.Description = string.Join(", ", validValues);
        }
    }
}

The code for CustomParametersFilter is a starting point, but it can be adjusted to suit your needs. IParameter (and OpenApiParameter) offer many more options.

Lucas S.
  • 702
  • 2
  • 11
  • 22
  • I am getting Cannot resolve scoped service 'Database.Data.SchemaContext' from root provider. – kafka May 22 '20 at 12:56
  • Have you registered any implementation of this `SchemaContext` class, in the `ConfigureServices` method? – Lucas S. May 22 '20 at 14:26
  • Yes - it is registered as you stated above .. The error occur when I call my swagger endpoint swagger/v1/swagger.json – kafka May 25 '20 at 17:24
  • `Cannot resolve scoped service 'Database.Data.SchemaContext' from root provider.` is the error I am getting – kafka May 27 '20 at 20:06