Skip to content

Cannot have multiple response types for same status code #2743

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

Open
nithinbandaru1 opened this issue Nov 29, 2023 · 2 comments
Open

Cannot have multiple response types for same status code #2743

nithinbandaru1 opened this issue Nov 29, 2023 · 2 comments
Labels
help-wanted A change up for grabs for contributions from the community

Comments

@nithinbandaru1
Copy link

nithinbandaru1 commented Nov 29, 2023

I am doubtful that if this existing issue (#2413, #329) will be reopened, so here I open a new one.

OneOf is now supported by open-api standard. I believe this is a basic feature that would be useful for many.

I wonder how much trouble, the swagger docs now available in internet generated by .NET applications would be creating for consumers of those APIs. 🙂

https://spec.openapis.org/oas/v3.1.0#discriminator-object

@zleao
Copy link

zleao commented Mar 12, 2024

This would definitely be a very nice feature to add... even if just the support for multiple schemas for same status code.
Currently don't have the availability for it, but could definitely help on the testing part, if someone would be interested on going forward with this.

@martincostello martincostello added the help-wanted A change up for grabs for contributions from the community label Apr 14, 2024
@Brads3290
Copy link

Until this is implemented, I just wrote a basic operation filter that accomplishes this. Feel free to use it.

public class MultipleProducesOperationFilter : IOperationFilter {

    public void Apply(OpenApiOperation operation, OperationFilterContext context) {
        var attrs = context.MethodInfo.GetCustomAttributes(false)
            .OfType<ProducesResponseTypeAttribute>()
            .GroupBy(x => x.StatusCode)
            .Select(g => new { StatusCode = g.Key, Attributes = g.ToArray() })
            .ToList();

        var duplicateAttrs = attrs
            .Where(x => x.Attributes.Length > 1)
            .ToList();

        if (duplicateAttrs.Count == 0) {
            return;
        }

        // We have multiple attributes. Rebuild the responses.
        
        foreach (var details in duplicateAttrs) {
            var schema = BuildSchemaFromAttrs(details.Attributes, context);
            
            // I don't think there's a scenario where we would have an attribute on the method, but not
            // also have a response for the corresponding code in the dict. If that does happen, this will throw.
            var response = operation.Responses[details.StatusCode.ToString()];

            foreach (var contentType in response.Content.Keys) {
                var contentDetails = response.Content[contentType];
                contentDetails.Schema = schema;
            }
        }
    }

    private static OpenApiSchema BuildSchemaFromAttrs(IEnumerable<ProducesResponseTypeAttribute> attrs, OperationFilterContext context) {
        var schemas = new List<OpenApiSchema>();
        foreach (var attr in attrs) {
            // Expect that these will be generated as references, not inline
            var schema = context.SchemaGenerator.GenerateSchema(attr.Type, context.SchemaRepository);
            schemas.Add(schema);
        }

        return new() {
            OneOf = schemas,
        };
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help-wanted A change up for grabs for contributions from the community
Projects
None yet
Development

No branches or pull requests

4 participants