Thanks for the brilliant library!
There are a bunch of situations in which allOf is inserted into the schema due to multiple annotations supplying the same field. I understand that this is the intended behavior.
Here are some examples:
I understand the reasoning behind the choice but the problem is that it leads to difficult to predict consequences.
For example, this leads to an allOf element being inserted along with both descriptions for the size field:
@Schema(description = "available sizes")
public enum Size {
SMALL, MEDIUM, LARGE;
}
public class TShirt {
@Schema(description = "T-Shirt size")
public Size size;
}
whereas this leads to no allOf and a single description because the Size and the size descriptions are identical:
@Schema(description = "available sizes")
public enum Size {
SMALL, MEDIUM, LARGE;
}
public class TShirt {
@Schema(description = "available sizes")
public Size size;
}
In more complex cases with inheritance, it can be quickly hard to reason about what you are going to get and to provide consistency across a schema. Imagine the case where the enum is exposed in 2 different fields that don't have the same value, then you get 2 different results. Across large APIs (100+ classes) this gets difficult to reason about fast.
I am migrating from Jackson's deprecated module schema and this seemed to take a "closest one wins" approach. In the first example, the description would have been "T-Shirt size" for example.
I can't see a way to get this behavior using the current API. I can strip my nested classes/enums of having class level annotations but this doesn't work if I have a class that is exposed at the root level and also nested in a different context. It is also brittle because as soon as a dev adds one back in, but only with a different value, will it lead to an unexpected allOf.
I have worked around this for now by post-processing the schema as follows. This only works for me because I know I don't have any "genuine" allOf in my schema but this would need to be more complex if I did.
private static void flattenAllOf(ObjectNode schema) {
flattenAllOfInChildren(node);
JsonNode allOf = node.get("allOf");
if (allOf == null || !allOf.isArray()) return;
node.remove("allOf");
allOf.forEach(entry -> {
if (entry instanceof ObjectNode entryObj) {
entryObj.properties().forEach(e -> {
node.set(e.getKey(), e.getValue());
});
}
});
}
private static void flattenAllOfInChildren(ObjectNode node) {
node.properties().forEach(entry -> {
if (entry.getValue() instanceof ObjectNode child) {
flattenAllOf(child);
} else if (entry.getValue() instanceof ArrayNode array) {
array.forEach(item -> { if (item instanceof ObjectNode o) flattenAllOf(o); });
}
});
}
Thanks for the brilliant library!
There are a bunch of situations in which
allOfis inserted into the schema due to multiple annotations supplying the same field. I understand that this is the intended behavior.Here are some examples:
I understand the reasoning behind the choice but the problem is that it leads to difficult to predict consequences.
For example, this leads to an
allOfelement being inserted along with both descriptions for thesizefield:whereas this leads to no
allOfand a single description because theSizeand thesizedescriptions are identical:In more complex cases with inheritance, it can be quickly hard to reason about what you are going to get and to provide consistency across a schema. Imagine the case where the enum is exposed in 2 different fields that don't have the same value, then you get 2 different results. Across large APIs (100+ classes) this gets difficult to reason about fast.
I am migrating from Jackson's deprecated module schema and this seemed to take a "closest one wins" approach. In the first example, the description would have been "T-Shirt size" for example.
I can't see a way to get this behavior using the current API. I can strip my nested classes/enums of having class level annotations but this doesn't work if I have a class that is exposed at the root level and also nested in a different context. It is also brittle because as soon as a dev adds one back in, but only with a different value, will it lead to an unexpected
allOf.I have worked around this for now by post-processing the schema as follows. This only works for me because I know I don't have any "genuine"
allOfin my schema but this would need to be more complex if I did.