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

Allow defining arrays with multiple types of items #1683

Closed
mklueh opened this issue Dec 10, 2023 · 6 comments
Closed

Allow defining arrays with multiple types of items #1683

mklueh opened this issue Dec 10, 2023 · 6 comments
Labels
question Further information is requested

Comments

@mklueh
Copy link

mklueh commented Dec 10, 2023

Hello. I found this issue in the microprofile repository and participated there, as I`m missing a feature that should exist according to the specification:

using Schema with anyOf / oneOf / allOf

@Data
@Builder
@AllArgsConstructor
public class SomeResponseObject {

    private long page;

    private long pages;

    @Schema(type = ARRAY, oneOf = {SomeItem.class, SomeOtherItem.class})
    private List<BaseClass> items;
}

Which however, against expectations leads to this schema

 "SomeResponseObject" : {
        "type" : "object",
        "properties" : {
          "page" : {
            "format" : "int64",
            "type" : "integer"
          },
          "pages" : {
            "format" : "int64",
            "type" : "integer"
          },
          "items" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/BaseClass"
            },
             "oneOf" : [ {
              "$ref" : "#/components/schemas/SomeItem"
            }, {
              "$ref" : "#/components/schemas/SomeOtherItem"
            } ]
          }
        }
      },

which generates his typescript object

    SomeResponseObject: {
      /** Format: int64 */
      page?: number;
      /** Format: int64 */
      pages?: number;
      items?: components["schemas"]["SomeItem"] | components["schemas"]["SomeOtherItem"];
    };

This is the current vs the expected result discussed here openapi-ts/openapi-typescript#1421 (comment):

image

The guys from Eclipse have provided multiple solution ideas like this

eclipse/microprofile-open-api#425 (comment)

    @Schema(type = ARRAY, items = @PropertySchema(oneOf = {BaseClass.class, SomeItem.class, SomeOtherItem.class}))
    private List<BaseClass> items;

which would apply the Schema to the Item(s) instead of the list property.

As the issue is already almost 4 years old and I'm not sure how the relation between the Eclipse and the Smallrye project is, I have doubts that a solution will find its way into the Quarkus ecosystem anytime soon. That's why I repost it here.

@MikeEdgar
Copy link
Member

Hi @mklueh, I am a contributor to both projects. The SmallRye implementation of MP OpenAPI aims to follow the spec as closely as possible and of course pass the TCK tests. Generally, we avoid extending the API (adding annotations or new interfaces).

Until the change is available in the MP OpenAPI spec to specify items in a @Schema, a common pattern is to use an intermediate class to hold the item schema, example below. You don't need to use the class in your application, it only needs to be declared with the annotations as shown.

@Data
@Builder
@AllArgsConstructor
public class SomeResponseObject {

    private long page;

    private long pages;

    @Schema(implementation = BaseClassSchema[].class)
    private List<BaseClass> items;

    @Schema(oneOf = { SomeItem.class, SomeOtherItem.class })
    private static class BaseClassSchema { /* Schema marker class only */ }
}

@mklueh
Copy link
Author

mklueh commented Dec 14, 2023

@MikeEdgar thanks for the clarification and the workaround :) I'll try that out

@MikeEdgar
Copy link
Member

@mklueh , you could of course place @Schema(oneOf = { SomeItem.class, SomeOtherItem.class }) directly on BaseClass for a similar result.

@mklueh
Copy link
Author

mklueh commented Dec 19, 2023

@MikeEdgar thank you, seems to work :)

@MikeEdgar
Copy link
Member

@mklueh would you be OK with closing this issue? We'll need to work in the spec project anyway to make the enhancements to the annotations that is being discussed there.

@mklueh
Copy link
Author

mklueh commented Jan 9, 2024

@MikeEdgar sure 😊

@MikeEdgar MikeEdgar added the question Further information is requested label Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants