Nswag: oneOf support in request body schema for NSwag.Generation.AspNetCore

Created on 28 Nov 2019  路  5Comments  路  Source: RicoSuter/NSwag

According to the checked list item in #945, oneOf should be supported. Specifically what we need is oneOf support for requestBody schemas, as shown in the first example here:

paths:
  /pets:
    patch:
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'

We're having difficulties implementing it, though, as we find no way to decorate our ASP.NET Core code to generate an OpenAPI document with requestBody.content.application/json.schema.oneOf defined.

Instead, NSwag attempts to generate an OpenAPI document with duplicate path definitions, causing the following code to be invoked and exception to be thrown:

https://github.com/RicoSuter/NSwag/blob/085e8aeb95e4f1723f956fa6137bbc07bd5527a6/src/NSwag.Generation.AspNetCore/AspNetCoreOpenApiDocumentGenerator.cs#L260-L263

Ideas and pointers in the right direction would be highly appreciated.

NJsonSchema NJsonSchema.CodeGeneration.CSharp NJsonSchema.CodeGeneration.TypeScript enhancement

All 5 comments

Having this would be useful in a scenario where routing is done based on a property in the request body.

public class PaymentOrderController : ApiController
{
  [HttpPost("{paymentOrderId}")
  [AcceptsOperation("set-paymentorder-date")]
  public IAction SetPaymentorderDate([FromBody] PaymentOrderDateRequest request)
  {
    //... Shortened for brevity
    return Ok(updatedPaymentOrder);
  }
  [HttpPost("{paymentOrderId}")]
  [AcceptsOperation("set-paymentorder-state")]
  public IAction SetPaymentorderState([FromBody] PaymentOrderStateRequest request)
  {
    //... Shortened for brevity
    return Ok(updatedPaymentOrder);
  }
}

Consider the above example where routing is done on a JSON property. In such a case the URL or path of the resource is identical, but the request body and schema for the request is not identical.
As such a oneOf would be good to use here. But the result of trying to generate this schema is "The method 'post' on path '/paymentOrderId' is registered multiple times."

Using a oneOf in this case makes sense. But how would you then generate the clients? I consider this an edge case (and probably bad practice to return different schemas on the same route).

@RicoSuter, I could imagine this being implemented in a client with method overloading in languages that support it. It's only the request that is different, the response is equal for all operations. I don't agree that this is a bad practice and seeing how OpenAPI supports it through oneOf, I would think an OpenAPI implementation would do best to support it as well?

@RicoSuter, if we were to fork and implement this ourselves, would you accept a pull request? Also, could you please point us in the right direction on where and how you'd like to see this implemented in the existing source code?

@NullableInt, as pointed out by @RicoSuter on Twitter let's discuss whether聽we can use inheritance to make this work somehow.

Was this page helpful?
0 / 5 - 0 ratings