Well, I'm somewhat stuck here and I don't know which side is doing things it's not supposed to do. I'll try to outline the issue first.
I have an API call which is defined like this:
[HttpGet("GetProductionOrdersForOrderNumber")]
public List<ErpOrder> GetProductionOrdersForOrderNumber(int orderNumber, int? pos1, int? pos2)
{
// ...
}
It has four parameters where the first one is mandatory.
In my Program.cs, I setup the creation/publishing of a schema like this:
builder.Services.AddOpenApi(options =>
{
TypeTransformer.MapType<decimal>(new OpenApiSchema { Type = JsonSchemaType.Number, Format = "decimal" });
TypeTransformer.MapType<decimal?>(new OpenApiSchema { Type = JsonSchemaType.Number | JsonSchemaType.Null, Format = "decimal" });
TypeTransformer.MapType<int?>(new OpenApiSchema {Type = JsonSchemaType.Integer | JsonSchemaType.Null, Format = "int32"});
options.AddSchemaTransformer(TypeTransformer.TransformAsync);
});
Note that I am explicitly not specifying a MapType for the non-nullable int type. The schema generated looks like this:
"/api/ProductionStateViewer/GetProductionOrdersForOrderNumber": {
"get": {
"tags": [
"ProductionStateViewer"
],
"parameters": [
{
"name": "orderNumber",
"in": "query",
"schema": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"integer",
"string"
],
"format": "int32"
}
},
{
"name": "pos1",
"in": "query",
"schema": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"null",
"integer"
],
"format": "int32"
}
},
{
"name": "pos2",
"in": "query",
"schema": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"null",
"integer"
],
"format": "int32"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ErpOrder"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ErpOrder"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ErpOrder"
}
}
}
}
}
}
}
},
Note that the orderNumber parameter is generated as type integer or string with a specified format int32. I understand that this can be expected because I read somewhere that it's part of the query which is transferred as a string. Yet, with that argument basically each parameter in a query is a string which renders the type irrelevant.
Thinking how this could probably work I tried to create a client with Kiota. To do so, I used the following command:
kiota generate --openapi http://localhost:1037/openapi/v1.json
--language CSharp --class-name ErpInterfaceService
--namespace-name ErpInterfaceServiceRest
--output d:\temp\kiota-test
Kiota will now throw the following warning:
OpenAPI warning: #/paths/~1api~1ProductionStateViewer~1GetProductionOrdersForOrderNumber/get/parameters/0/schema - The format int32 is not supported by Kiota for the type Integer, String and the string type will be used.
Of course, the generated API call in C# will now have orderNumber as a string? parameter which is the opposite of what I want. The remaining parameters are correctly generated as int?.
Of course I could add the line
TypeTransformer.MapType<int>(new OpenApiSchema { Type = JsonSchemaType.Integer, Format = "int32" });
to my initialization which makes .AddOpenApi create the int type (similar to the nullable int types with the other parameters) and Kiota behave as expected but I would like to understand what is actually the "correct" way to do this? Who is in the wrong here: AddOpenApi for not creating an int where there is a need for an int?, or Kiota for complaining that the string|int construct cannot be an int at code level?
I understand that I could probably send the request GetProductionOrdersForOrderNumber?orderNumber=Stupid but shouldn't that be handled at some different place?
Now who is in the wrong here?