question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Optionally document query parameters in swagger and remove them from body

See original GitHub issue

I’d like to request a possible improvement - in my case I have an endpoint that accepts a JsonPatchDocument and another query parameter.

Everything works OK in the integration tests and also if I send the query parameter manually. However we are planning to use auto-generated clients and currently the query parameter does not show up in the swagger (I’m overriding some things to make the JsonPatchDocument work, as per issue #77).

For now I’ve started adding the [FromQuery] attribute and use the following SwaggerProcessor to make these specific parameters show only as query parameters:

public class QueryParametersProcessor : IOperationProcessor
{
    public bool Process(OperationProcessorContext context)
    {
        var aspNetCoreContext = (AspNetCoreOperationProcessorContext)context;
        var apiDesc = aspNetCoreContext.ApiDescription;
        var returnType = apiDesc.ParameterDescriptions.FirstOrDefault()?.Type;

        if (returnType is null) return true;

        var op = context.OperationDescription.Operation;

        var reqParamDescriptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        if (op.RequestBody is not null)
        {
            foreach (var c in op.RequestBody.Content)
            {
                foreach (var prop in c.Value.Schema.ActualSchema.ActualProperties)
                {
                    reqParamDescriptions[prop.Key] = prop.Value.Description;
                }
            }
        }

        // This part currently needs reflection
        // //also add descriptions from user supplied summary request params overriding the above
        // if (endpoint.Summary is not null)
        // {
        //     foreach (var param in endpoint.Summary.Params)
        //     {
        //         reqParamDescriptions[param.Key] = param.Value;
        //     }
        // }


        var parameters = op.Parameters;
        var props = returnType.GetProperties(
            BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
        foreach (var property in props)
        {
            var attrs = property.GetCustomAttributes(true);
            if (attrs.Length <= 0) continue;

            foreach (var attr in attrs)
            {
                if (attr is not FromQueryAttribute) continue;
                if (parameters.Any(p => p.Kind == OpenApiParameterKind.Header && p.Name == property.Name)) continue;

                parameters.Add(new OpenApiParameter
                {
                    Name = property.Name,
                    IsRequired = false,
                    Schema = JsonSchema.FromType(property.PropertyType),
                    Kind = OpenApiParameterKind.Query,
                    Description = reqParamDescriptions.GetValueOrDefault(property.Name)
                });

                foreach (var parameter in parameters)
                {
                    if (parameter.Kind == OpenApiParameterKind.Body)
                        Remove(parameter.ActualSchema, property.Name);
                }
            }
        }

        return true;
    }

    private static void Remove(JsonSchema schema, string? key)
    {
        if (key is null) return;

        schema.Properties.Remove(key);

        foreach (var s in schema.AllOf.Union(schema.AllInheritedSchemas))
        {
            Remove(s, key);
        }
    }
}

Could this be added to the library itself? Right now I’m not, for example, correctly overriding the description because I’d have to use reflection. I even ended up using this attribute in other operations to properly document them.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
dj-nitehawkcommented, Oct 25, 2022

@gius MetadataTypeAttribute would only work for partial classes right?

one option would be to write a custom nswag operation processor and do exactly what the default processor does when it encounters a QueryParam attribute.

https://github.com/FastEndpoints/FastEndpoints/blob/6bc0332db716243355feef3f332a7143201cbfc4/Src/Swagger/OperationProcessor.cs#L235

1reaction
jorge-ribeiro-evalteccommented, Apr 7, 2022

Nevermind, got it here! Closing the issue, thanks for the help!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Describing Parameters
Each parameter has name , value type (for primitive value parameters) or schema (for request body), and optional description . Here is an...
Read more >
Remove extra parameters from Swagger
I'm using Swagger API and later OpenAPI Specification for many years. And earlier I tried to use the SpringFox for automatic building of ......
Read more >
Omit empty and optional values in form data · Issue #5303
Parameters allow for an allowEmptyValue property which is in the openapi spec, when this value is true swagger-ui renders a checkbox ( ...
Read more >
Using Optional and Nullable Properties in API Requests
Learn how optional and nullable properties can be used flexibly in combinations in each parameter of your API requests made from a SDK....
Read more >
Using OpenAPI and Swagger UI
This guide explains how your Quarkus application can expose its API description through an OpenAPI specification and how you can test it via...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found