swagger-core
swagger-core copied to clipboard
JSONObject schema being referenced instead of example being populated
Not entirely sure if this is a feature or a bug or even if there is a way to fix it.
I have the following schema annotation in code that has org.json.simple JSONObject type:
@Schema(
description = "userCredentials",
example = "{\"id\": 1012}"
)
private JSONObject userCredentials;
In the openapi.yaml thats generated, I get:
...
userCredentials:
$ref: '#/components/schemas/JSONObject'
...
What I was expecting was something like this:
...
userCredentials:
description: userCredentials
example:
id: 1012
...
There are a bunch of other areas in the codebase that use JSONObject type (some with schema annotations and some without), and some of those schemas do display correctly for JSONObject, however there are a few that just use a reference to the JSONObject schema.
So my questions are:
- Why is a JSONObject schema even being created in the first place?
- Is there a way I can prevent swagger-core from generating a schema for JSONObject (or any particular type)?
- Is there a way I can force particular variables to use the local schema info instead of a reference to JSONObject?
I found a solution with the following converter:
private static class DuplicateTypeConverter implements ModelConverter {
private final Class<?> clazz;
public DuplicateTypeConverter(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public Schema<?> resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
if (type.isSchemaProperty()) {
JavaType _type = Json.mapper().constructType(type.getType());
if (_type != null) {
if (clazz.equals(_type.getRawClass())) {
if (context.getDefinedModels().containsKey(clazz.getSimpleName())) {
type.setResolveAsRef(false);
}
}
}
}
if (chain.hasNext()) {
return chain.next().resolve(type, context, chain);
} else {
return null;
}
}
}
I still think this is an issue with swagger-core. I would think in ModelResolver.java, lines 869-871:
if (context.getDefinedModels().containsKey(model.getName())) {
model = new Schema().$ref(constructRef(model.getName()));
}
it should instead be:
if (context.getDefinedModels().containsKey(model.getName()) && context.getDefinedModels().get(model.getName()).equals(model)) {
model = new Schema().$ref(constructRef(model.getName()));
}
So basically if the metadata of the models differ, we should not use a reference, but instead return the schema. The only concern I have with submitting this is that I don't know if it goes against the specification
An alternate solution would be to include setResolveAsRef in the Schema type, so we can force specific models to not use a reference, but once again this is really just a bandaid over the issue at hand.