Open leorg99 opened 1 month ago
@devhl-labs
As it relates to #19893, I wrote a small script to transformed the filter* query parameters to style: deepObject
, explode: true
, and replaced the schema to have two properties.
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers;
using Microsoft.OpenApi.Writers;
OpenApiDocument document;
using (var httpClient = new HttpClient())
{
var stream = await httpClient.GetStreamAsync("https://app.files.com/api/rest/v1/swagger_doc.json");
var reader = new OpenApiStreamReader();
document = reader.Read(stream, out var diagnostic);
}
foreach (var (path, item) in document.Paths)
{
foreach (var (operationType, operation) in item.Operations)
{
for (var i = 0; i < operation.Parameters.Count; i++)
{
var parameter = operation.Parameters[i];
if (parameter.Name.StartsWith("filter"))
{
parameter.Style = ParameterStyle.DeepObject;
parameter.Explode = true;
parameter.Schema = new OpenApiSchema
{
Title = "FilterParameter",
Type = "object",
Properties = new Dictionary<string, OpenApiSchema>()
{
["field"] = new OpenApiSchema() { Type = "string" },
["value"] = new OpenApiSchema() { Type = "string" }
}
};
}
}
}
// Serialize and save the modified OpenAPI document to a new file
await using var streamWriter = new StreamWriter("updated.yaml");
var writer = new OpenApiYamlWriter(streamWriter);
document.SerializeAsV3(writer);
}
Is your feature request related to a problem? Please describe.
The OpenAPI spec allows you to define parameters that can be rendered as
color[R]=100&color[G]=200&color[B]=150
.This can be written in the OpenApi yaml file as follows:
This is related to the issue in #19893
Describe the solution you'd like
To implement this, we need to modify several files.
Dealing with explode
First, we need to fix the signature of parameters with 'explode: true'. The spec states that when this is true:
Parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map.
For a query parameter with
name: color
, this would look likeSince the parameter can be used 0 or more times, we need to change the parameter to a collection type (like
List<T>
). This can be done by modifying Operation.Signature.mustache to add a{{#isExplode}} ... {{/isExplode}}
section.Next, we have to modify the following to add all the values in the
List<T>
parameter toNameValueCollection
https://github.com/OpenAPITools/openapi-generator/blob/008c1a42ef39100b38a86fc67344ea44d4f32a8f/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/api.mustache#L408-L443Support deepObject style
This along with
explode:true
allows us to specify query parameters assomeParam[field1]=value1&someParam[field2]=value2&someParam[field3]=value3
Since the parameter defines a schema with
type: object
andproperties
, the generator generates a model to represent this type. FordeepObject
styles, it only makes sense to define two properties: the field or column and the value. I think what we can do here is then generate a model that hasThen we can generate the query parameter as
Name[Column]=Value
Building on top of the changes we made previously,
Describe alternatives you've considered
Additional context