OpenAPI & ApiDeclarationFilter to add request headers

I’m trying to find a way to add a request header to all requests such that it is shown in the SwaggerUI.

I managed to achieve this by adding a special property all my request DTO’s and decorating that with APIMember attributes - but it meant then all my DTO’s need to then have all properties with APIMember attributes, and those inheriting from my service model classes need to then override all properties just to decorate with APIMember otherwise they no longer appear.

This got ugly real quick, so I looked for an alternative.

I thought it would be possible by setting the Parameters property within an ApiDeclarationFilter - but it seems to ignore my attempts to add anything other than an “Accept” header.

This is my AppHost:

public class AppHost : AppHostBase
{
    public AppHost()
        : base("ssTestServer2", typeof(PetServices).Assembly) { }

    public override void Configure(Container container)
    {
        this.Plugins.Add(new ServiceStack.Api.OpenApi.OpenApiFeature()
        {                
            ApiDeclarationFilter = declaration =>
            {
                declaration.Parameters.Clear();                    
                declaration.Parameters = new Dictionary<string, OpenApiParameter> { { "Accept", GetAcceptHeaderParameter() }, { "MyParam", GetMyCustomHeaderParameter() } };                    
            }
        });
    }

    private OpenApiParameter GetAcceptHeaderParameter()
    {
        return new OpenApiParameter
        {
            Type = OpenApiType.String,
            Name = "Accept",
            Description = "Accept Header",
            Enum = new List<string>() { "application/json", "application/xml" },
            In = "header",
            Required = true,
        };
    }

    private OpenApiParameter GetMyCustomHeaderParameter()
    {
        return new OpenApiParameter
        {
            Type = OpenApiType.Boolean,
            Name = "MyParam",
            Description = "My custom request parameter",                
            In = "header",
            Required = false
        };
    }
}

My model, request DTO and service:

public class Pet
{
    virtual public int? PetId { get; set; }
    virtual public string Name { get; set; }
}
    
[Route("/Pets", "GET")]
public class PetsGETManyRequest : IReturn<List<Pet>>
{
}

public class PetServices : Service
{    
    public List<Pet> Get(PetsGETManyRequest request)
    {
        return new List<Pet>();
    }
}

In the above code, the SwaggerUI shows the Accept parameter, but not my custom one:

As the Parameters property of ApiDeclarationFilter is a dictionary of <string, OpenApiParameter>, the implication I thought that multiples are permitted and supported.

From my research so far, this looks like it is probably a limitation of SwaggerUI. Is there another way to achieve what I want?

1 Like

You need to add parameter to declaration.Paths, the Parameters in the root just contains parameters definitions which can be referenced in operation, not global parameters for all operations.

            Plugins.Add(new OpenApiFeature()
                {
                    ApiDeclarationFilter = api =>
                    {
                        foreach (var path in api.Paths)
                        {
                            path.Value.Parameters.Add(GetMyCustomHeaderParameter());
                        }
                    }
                }

Brilliant! thanks - tested and working!