RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.69k stars 1.24k forks source link

CSharpGenerator Creates multiple clients and interfaces by default #2660

Open rolandpop opened 4 years ago

rolandpop commented 4 years ago

While generating a C# client for pipedrive I've encountered the following problem:

The C# client generator created multiple clients and interfaces which caused buid errors. The Yaml : https://developers.pipedrive.com/docs/api/v1/pipedrive-api.yaml

I run the generator with the following arguments (in VS project file):

 <ItemGroup>
    <OpenApiReference Include="OpenApi\pipedrive-openApi.yaml" Options="/ExceptionClass:PipedriveException /GenerateClientInterfaces:true /ClientClassAccessModifier:internal" ClassName="PipedriveClient" Namespace="Services" />
  </ItemGroup>

The result of building the project generated 3 "PipedriveClient"s two of which handle 1 operation each:

'/pipelines/{id}/conversion_statistics':
    get:
      summary: Get deals conversion rates in pipeline
      description: Returns all stage-to-stage conversion and pipeline-to-close rates for given time period.
      tags:
        - Pipelines
      security:
        - api_key: []
        - oauth2:
            - 'deals:read'
            - 'deals:full'
      parameters:
        - $ref: '#/components/parameters/PipelineID'
        - in: query
          name: start_date
          required: true
          schema:
            type: string
            format: date
          description: Start of the period. Date in format of YYYY-MM-DD.
        - in: query
          name: end_date
          required: true
          schema:
            type: string
            format: date
          description: End of the period. Date in format of YYYY-MM-DD.
        - in: query
          name: user_id
          schema:
            type: number
          description: 'ID of the user who''s pipeline metrics statistics to fetch. If omitted, the authorized user will be used.'
      responses:
        '200':
          $ref: '#/components/responses/EmptySuccess'

and the other:

 '/pipelines/{id}/movement_statistics':
    get:
      summary: Get deals movements in pipeline
      description: Returns statistics for deals movements for given time period.
      tags:
        - Pipelines
      security:
        - api_key: []
        - oauth2:
            - 'deals:read'
            - 'deals:full'
      parameters:
        - $ref: '#/components/parameters/PipelineID'
        - in: query
          name: start_date
          required: true
          schema:
            type: string
            format: date
          description: Start of the period. Date in format of YYYY-MM-DD.
        - in: query
          name: end_date
          required: true
          schema:
            type: string
            format: date
          description: End of the period. Date in format of YYYY-MM-DD.
        - in: query
          name: user_id
          schema:
            type: number
          description: 'ID of the user who''s pipeline statistics to fetch. If omitted, the authorized user will be used.'
      responses:
        '200':
          $ref: '#/components/responses/EmptySuccess'

the rest of the operations are handled in the 3rd client...

I managed to force the generator to create only one client class with the following setting: OperationGenerationMode:SingleClientFromOperationId

Would be nice to know what happened and why it generated 3 clients.

RicoSuter commented 4 years ago

The default class name is “{controllerName}Client” but this only works with operationIds in the form “{controllerName}_{operationName}” which is the default for NSwag generated specs (this way each controller generates one client and operation/method names are preserved).

In your case you’re “hardcoding” the client names and thus you need a SingleClient* generation mode.

j-hap commented 4 months ago

When using Visual Studio and not setting the className, Visual Studio currently sets a hardcoded non-template one, which does not play nice with the default MulipleClient OperationGenerationMode, see https://developercommunity.visualstudio.com/t/OpenApiReference-default-className-break/10639639