-
Notifications
You must be signed in to change notification settings - Fork 83
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
It is not possible to create Schema with array of referenced items #425
Comments
Yes that is the contract for the |
One thing you could try is creating a dummy class/interface like this: interface NamedList extends List<Named> Then you can use that as the implementation class for the annotation. |
@MikeEdgar @arthurdm any thoughts on other workarounds? I feel like I'm missing an obvious approach, but I can't think of anything. |
What about the following where @Schema(
required = true,
description = "Some description...",
type = SchemaType.ARRAY,
implementation = NamedBean.class) |
Hi @MikeEdgar, when I'm using 'implementation' in combination with SchemaType.ARRAY, then in result final document I'm getting a full description of schemas which are over all fields inside NamedBean, not $ref field (if I understand correctly. what you mean). |
@KrystianRos - did you try @EricWittmann's approach of using an interface? |
Sitting on the same boat as @KrystianRos. |
@KrystianRos, @0xqab - I would suggest you try either (1) implementing an @0xqab mentioned the use of Payara, which implementation are you using @KrystianRos ? I expect the type = ARRAY with |
…lrye-smallrye-parent-23 Bump smallrye-parent from 22 to 23
This issue was discussed in the 2023-10-02 meetup call. One proposed solution would be to allow for the With that enhancement, developers could write something like the code below and get the expected result. @Schema(required = true, description = "Some description...")
List<@Schema(ref = "name") MyNameBean> variableName; variableName:
type: array
description: Some description...
items:
$ref: '#/components/schemas/name1' |
We discussed this a little more on the 2023-10-09 meetup call. For reference, this should currently work, as long as you want to reference the schema generated for @Schema(required = true, description = "something")
List<MyNameBean> variableName; Whether the schema for Here are the options we came up with for allowing a different schema to be referenced:
@MikeEdgar noted that option 1 would also let you specify the schema for objects in a map like this: Map<String, @Schema(oneOf={A.class, B.class}) Object> variableName; Currently you can do this with |
We noted a few shortcomings for Option 1:
In these three scenarios, Option 3 would provide a way to declare the item schema, at the expense of requiring an extra object to host the I guess it depends how often we expect this to come up. If this is fairly rare, then I think it's more important to do something that covers every case, even if it's a bit clunky - it's better to have something clunky than to have to say "sorry, you can't do that". If we expect it to come up fairly often, then it may be worth considering doing both since I do think Option 1 is nicer (at least, when you don't have very much to put in the |
It looks odd, but this is actually possible: MyNameBean @Schema(required = true, description = "Some description...")[] variableName;
I agree, this would not be supported without some other class to reference, either using
Agreed, possibly this placement of the annotation is the strongest argument for adding |
Annotating the array type as suggested above may not actually be what is wanted. I need to look further into how the annotated is represented. |
It appears that when annotating with It's probably not what people are used to seeing since it would be reversed from the typical way of annotating fields, parameters, etc. However, it technically would allow for the schema to be expressed as needed when using arrays. @Schema(description = "Item description") String
@Schema(description = "Array description")[] variableName; Resulting schema: "variableName": {
"type": "array",
"description": "Array description",
"items": {
"type": "string",
"description": "Item description"
}
} |
We would want to make sure that we don't change the meaning of this: @Schema(description = "Item/array description?") String[] variableName; Today, this would refer to the field type (i.e. the array) whereas in the above example, it refers to the item type. @MikeEdgar also noted that there could be similar confusion over whether a method or its return type is the target of an annotation. |
From the call: we could look at how bean validation (or any other specs that have type_use annotations) handles type annotations on array fields like this. |
I was stumbling over this issue as well, trying to integrate OpenAPI in my application, and use oneOf / anyOf together with type ARRAY in my response object in the most (in my opinion) logical and intuitive way:
This however will lead to
which generates his typescript object
without any array type. This is the current vs the expected result discussed here openapi-ts/openapi-typescript#1421 (comment): While it does not do what I expected, I'm wondering what use case the actual result has and why it can't do what it should instead technically. I mean, when do I want to annotate a list with type array and anyOf / oneOf and really want something different as a result than specifying a type array that is one of the n types? Edit: I'm wondering if it would be possible to just do something like this to solve the issue or if there is any technical drawback / misunderstanding from my side, to just take anyOf etc into account if provided: |
@mklueh Thank you for your detailed breakdown of the problems you've had trying to the types right for an array. I'm sorry I've been really busy and still haven't had time to sit down and go through what you've written but I hope to get to it later this week. |
@mklueh's suggestion amounts to saying that when I'm not sure this is a good idea because while there are some fields that might be unambiguous, there are others which are not. In particular:
However, I note that this is also a problem we have for objects which we solved with the Would it make sense to have an For @mklueh's example, you could have @Schema(type = ARRAY, items = @PropertySchema(oneOf = {BaseClass.class, SomeItem.class, SomeOtherItem.class}))
private List<BaseClass> items; For the original example where you want to refer to a component schema for the item type you could have @Schema(required = true, description = "Some description...", items = @PropertySchema(ref="name))
List<MyNameBean> variableName; As-is, I don't think we can quite just use |
@Azquelt thanks for your detailed response.
Now I see the problem. The annotation would always refer to the types of the field it is annotating. What if Microprofile would automatically declare any inheritors of the used base type of the collection as allOf by default? Then no one would even have to bother with this case, except for more restrictive edge cases. (ex. only specific child classes should be allowed)
In case you want to refer to the item, wouldn't you then place the annotation on top of the item's class instead?
Just to make sure I understand you correctly: Does that mean you could declare a field:
to tell Microprofile the Collection type should be seen as a String? And why is the
That would also be nice. Or the property should be named @Schema(type = ARRAY, itemSchema = @ItemSchema(oneOf = {BaseClass.class, SomeItem.class, SomeOtherItem.class}))
private List<BaseClass> items; to make it a bit clearer
Also nice, but not sure which of both variants would be more straightforward from a user's perspective...I'd generally advocate against yet another annotation, but thinking about it, maybe
|
I agree that using Adding a default for |
On the call we broadly agreed that reusing I also note that this would provide another way to do #445 if you can't annotate the item class. |
Great! Is there a rough timeframe for when a solution might be released? @Azquelt @MikeEdgar Considering this issue is already 3.5 years old, are those types of changes rather slow to push forward in this project, because of standardization and compatibility issues or is there no real hurdle? |
The things that need to be done to get this in the next release are:
The next release is likely to be some time next year, around the next major MicroProfile release. Additionally, before we can do a release, we also need someone to have implemented it and passed the TCK (both so that people can actually use it, and to ensure we haven't put anything in the spec that's actually impossible to implement). The main hurdle is that most of us are tied up working on other projects so there hasn't been a lot of work on MP OpenAPI recently. If you'd like to propose a PR to make the API changes and add TCKs for this feature that would be very welcome, otherwise one of us will get to it eventually. |
@Azquelt thanks :) One thing confuses me when looking at the TCK It seems the Wouldn't it be better to deprecate |
Versions: 1.0.1, 1.1.2, 2.0-MR1
I'm using the following annotation for schema:
@Schema(required = true, description = "Some description...", type = SchemaType.ARRAY, ref = "name1")
What I'm getting is:
What I expect to get:
It looks like ref is overriding all of data in @Schema object. I have tried a lot of modifications for mentioned annotation, but only pseudo-success is when I have add an 'implementation' element pointing to class- but that's not satisfying solution.
I'm sorry for not pasting original content, but it's protected by contract.
The text was updated successfully, but these errors were encountered: