OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.04k stars 6.38k forks source link

[BUG][csharp][dotnet] Query parameters with explode: true not supported #17991

Open fghpdf opened 5 months ago

fghpdf commented 5 months ago

Bug Report Checklist

Description

In OpenAPI 3.0, we can wrap query params into one param by using style: form and explode: true. (Ref: https://swagger.io/docs/specification/serialization/)

And the generated C# code has only one param in this method.

[Expected] But the param cannot be converted into the correct HTTP query param, eg. in CURL:

curl -X 'GET' \
  'https://raw.githubusercontent.com/resource?lang=en&scope=mobile' \ # correct
  -H 'accept: application/json'

[Actual] The generated code will convert the object's root name into the query param, eg. in CURL:

curl -X 'GET' \
  'https://raw.githubusercontent.com/resource?filter=XXXParam' \ # wrong
  -H 'accept: application/json'
openapi-generator version

v7.3.0

OpenAPI declaration file content or url
info:
  title: Example
  version: 1.0.0
openapi: 3.0.3
paths:
  "/resource":
    parameters:
      - name: filters
        in: query
        required: true
        schema:
          type: object
          additionalProperties:
            type: string
          example:
            lang: en
            scope: mobile
        style: form
        explode: true
    get:
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                properties:
                  id:
                    type: string
                type: object
Generation Details
openapi-generator-cli generate -g csharp --additional-properties=library=httpclient --additional-properties=targetFramework=net6.0 -i file.yaml 
Steps to reproduce
  1. Generate the code
  2. new ResourceGetFiltersParam() and put some value into it
  3. Call await DefaultApi().resourceGet(param)
  4. Check the result
Related issues/PRs
Suggest a fix

In the ClientUtils.mustache, the generated code will call the function ParameterToMultiMap and the process will go to this step https://github.com/OpenAPITools/openapi-generator/blob/275ed9296dea4a1a894cc5b3402b5b8f3a61e7d7/modules/openapi-generator/src/main/resources/csharp/ClientUtils.mustache#L87-L90

Like the suggestion in #16435 , we can use the similar way to solve this problem:

                  {{#isExplode}}
                    {{#isModel}}
                      for (let key of Object.keys({{paramName}})) {
                        localVarQueryParameter[key] = ({{paramName}} as any)[key];
                      }

                    {{/isModel}}
                    {{#isPrimitiveType}}
                        localVarQueryParameter['{{baseName}}'] = {{paramName}};
                    {{/isPrimitiveType}}
                  {{/isExplode}}
                  {{^isExplode}}
                      localVarQueryParameter['{{baseName}}'] = {{paramName}};
                  {{/isExplode}}

[!NOTE] I want to open a Pull Request to solve this issue. ✍🙏

PrincessMadMath commented 2 months ago

Also specific to the sub-template generichost which override the api.mustache and ClientUtils.mustache the method ParameterToMultiMap() just doesn't exist which means that the exploded "explode: true not supported" bugs also apply to other use case like array.

For this OpenAPI document

info:
  title: Example
  version: 1.0.0
openapi: 3.0.1
paths:
  /test-array:
    get:
      tags:
        - Test
      parameters:
        - name: numbers
          in: query
          required: true
          style: form
          explode: true
          schema:
            type: array
            items:
              type: integer
              format: int32
      responses:
        '200':
          description: Success

[Expected] Should separate item from an array using &

https://localhost:8080/test-array?numbers=1&numbers=2&numbers=3

[Actual] Separates with comma

https://localhost:48666/test-array?numbers=1,2,3

We are also willing to open a Pull Request to make the required fixes for the generichost library.

keenangraham commented 1 month ago
Screenshot 2024-07-08 at 7 08 55 PM

Looks like this is also a problem in the Python client generator.