Matze
Matze

Reputation: 5508

NSwag: Generation of a C# client results in invalid code

I am trying to generate a C# client for the Trello API. Therefore I have downloaded the Open API specification from https://developer.atlassian.com/cloud/trello/swagger.v3.json and run the following nswag command from the bash.

nswag openapi2csclient /input:swagger.v3.json \
    /classname:TrelloClient \
    /namespace:Integrations.Trello \
    /output:TrelloClient.cs \
    /GenerateClientInterfaces:True \
    /GenerateExceptionClasses:True \
    /GenerateClientClasses:True \
    /DisposeHttpClient:False \
    /OperationGenerationMode:SingleClientFromOperationId

The code generation completes without errors, but the generated code does not compile because it contains many errors. For example, some of the generated method names contain invalid expressions like =idAsync, or method signatures have ambiguous parameters (for instance, multiple key and token parameters of type string). The following method declaration has been generated for the GetMembers method, which is obviously the wrong syntax.

System.Threading.Tasks.Task<Member> GetMembers=idAsync(
    string key, string token, string id, string actions, string boards, BoardBackgrounds? boardBackgrounds, 
    BoardsInvited? boardsInvited, BoardFields? boardsInvited_fields, bool? boardStars, string cards, 
    CustomBoardBackgrounds? customBoardBackgrounds, CustomEmoji2? customEmoji, CustomStickers? customStickers, 
    MemberFields? fields, string notifications, Organizations? organizations, 
    OrganizationFields? organization_fields, bool? organization_paid_account, 
    OrganizationsInvited? organizationsInvited, OrganizationFields? organizationsInvited_fields, 
    bool? paid_account, bool? savedSearches, Tokens? tokens);

Are there any special options that need to be set when processing an Open API specification document of version 3?

Upvotes: 1

Views: 3423

Answers (1)

Matze
Matze

Reputation: 5508

I was able to solve syntax issues regarding the get-members method in the generated code by changing the OperationGenerationMode from SingleClientFromOperationId to SingleClientFromPathSegments. This works as a workaround because the =id term only appears in the operationId.

I inspected Trello´s Open API specification document and found out that the definition of get-members contained the =id term in the operationId; not sure if this is wrong in the spec, or the generator is not able to handle that case correctly. The definition of the get-members method looks like that (foreshortened):

... "/members/{id}":
{
   "get":
   {
       "tags": [],
       "operationId":"get-members=id",
       "parameters" ...
   }
}

As a sidenote, the reason why I use the SingleClient... operation modes is that Nswag also adds GeneratedCode attributes to any partial class and interface which also results in invalid code (this attribute can only be applied once). The SingleClient... operation mode solves that.

What remains is the problem that NSwag generates methods with duplicated parameters, which has been reported as an issue, but is not solved yet; see https://github.com/RicoSuter/NSwag/issues/2560 for further information. Last but not least, I tried to remove the =id from the operationId and switched back to the SingleClientFromOperationId operation mode to check whether this does the trick, which is not the case.

I assume that NSwag is used by a broad audience which makes me think that this must be more related to the processed spec than Nswag. Thus, I looked up the spec for methods that have been reported by the C# compiler to have duplicated parameters. Here is an example.

...
{
    "name": "token",
    "in": "query",
    "description": "The API token to use",
    "required": true,
    "schema": {
        "$ref": "#/components/schemas/APIToken"
    }
},
{
    "name": "token",
    "in": "path",
    "description": "",
    "required": true,
    "schema": {
        "type": "string"
    }
}
...

So it seems that a method can have parameters of the same name, but they can appear in different places such a the query-string, or be part of the URL path. Then, it might be Nswag that produces the wrong output; if it is intended that both parameters can be sent to the API, then the generator should just prefix the names to avoid ambiguities, for instance, queryToken and pathToken, leaving it up to the developer to decide what parameter to use or to give a hint to the expected value (in case both parameters are required and expect different values).

Upvotes: 1

Related Questions