Optionally document query parameters in swagger and remove them from body
See original GitHub issueI’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:
- Created a year ago
- Comments:7 (3 by maintainers)
Top GitHub Comments
@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
Nevermind, got it here! Closing the issue, thanks for the help!