RicoSuter / NSwag

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

Duplicate properties in TypeScript generated client when [FromRoute] and [FromQuery] route attributes used #4753

Closed lukep-infotrack closed 6 months ago

lukep-infotrack commented 6 months ago

Hi, my team uses NSwag to generate our TypeScript clients and were using the webApiToOpenApi document generator and the openApiToTypeScriptClient via a MSBuild task. We recently updated to .NET 8 and version 14.0.2 of NSwag, in which webApiToOpenApi has been removed and so we've migrated to use the aspNetCoreToOpenApi document generator. Whilst there has been some differences I was able to generate basically identical TypeScript clients, except for a specific situation, where we use [FromRoute] and [FromQuery] in the same controller method. See example below:

// Controller
public class MessagesController : ApiControllerBase 
{
  [HttpGet("Messages")]
    public async Task<ActionResult<GettMessagesResponse>> GetMessagesAsync([FromRoute] int orderId,
 [FromQuery] GetMessagesQuery request, CancellationToken cancellationToken)
    {
        request.OrderId= orderId;
        return Ok(await Sender.Send(request, cancellationToken));
    }
}

// Query Class
public class GetMessagesQuery 
{
    public int OrderId { get; set; }
    public int? FromMessageId {get; set; ]
}

Previously in the generated .ts file, the [FromRoute] orderId was called orderIdPath and OrderId in the request object was omitted. However after the update, this is no longer happening and we are getting duplicate orderId properties on the method signature. See example below:

Before upgrade to 14.0.2

getMessages(orderIdPath: number, 
fromMessageId?: number | null | undefined, 
cancelToken?: CancelToken): Promise<IGetMessagesResponse> {

After upgrade to 14.0.2

getMessages(orderId: number, orderId?: number | undefined,  
fromMessageId?: number | null | undefined, 
cancelToken?: CancelToken): Promise<IGetMessagesResponse> 

We do a similar thing for Patch/Put routes however because the request object comes from the body, it isn't exploded and so we don't have the duplicate issue.

Ideally we don't want to have to rename variables to avoid this situation, this would affect a large portion of our application and would days/weeks to resolve. Is there a way we can ignore the duplicate property, mimic the previous behaviour out of the box or stop exploding the request object when its part of the query? I didn't see any configuration that made sense. If we can't resolve it out of the box, is there something we can add like an OperationProcess/Filter or the like that would assist?

lukep-infotrack commented 6 months ago

It seems [OpenApiIgnore] attribute will solve the duplication issue