Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oneOf support in request body schema for NSwag.Generation.AspNetCore #2548

Open
asbjornu opened this issue Nov 28, 2019 · 5 comments
Open

oneOf support in request body schema for NSwag.Generation.AspNetCore #2548

asbjornu opened this issue Nov 28, 2019 · 5 comments

Comments

@asbjornu
Copy link

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:

if (document.Paths[path].ContainsKey(operation.Method))
{
throw new InvalidOperationException($"The method '{operation.Method}' on path '{path}' is registered multiple times.");
}

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

@NullableInt
Copy link

NullableInt commented Dec 2, 2019

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."

@RicoSuter
Copy link
Owner

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).

@asbjornu
Copy link
Author

@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?

@asbjornu
Copy link
Author

@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?

@asbjornu
Copy link
Author

asbjornu commented Mar 3, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants