Description
Describe the bug
When working with Spring Data REST, the generated schema is an array of links, instead of a map of links (object with additionalProperties of type Link).
This bug is similar to #1090, but as it happens on the latest version (2.2.0), I'm opening a new one.
Here is a quick analysis of the problem:
- Spring Data REST serializes fields of type org.springframework.hateoas.Links as an object using
org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer - But SpringDoc sees org.springframework.hateoas.Links as a collection of org.springframework.hateoas.Link,
so it generates an array schema of #/components/schemas/Link instead - OpenApiHateoasLinksCustomizer should be able to help (needs to be registered though), but as the generated schema references #/components/schemas/Link directly instead of referencing a #/components/schemas/Links schema, it's useless
Workaround
I could customize the generated spec to fix the _links properties with this:
@Bean
GlobalOpenApiCustomizer linksCustomizer(SpringDocConfigProperties springDocConfigProperties) {
OpenApiHateoasLinksCustomizer linksCustomizer = new OpenApiHateoasLinksCustomizer(springDocConfigProperties);
return openApi -> {
//replace generated _links array schema with a reference to Links schema
openApi.getComponents().getSchemas().forEach((__, schema) -> {
Map properties = schema.getProperties();
if (properties != null && properties.containsKey("_links")) {
properties.put("_links", new ObjectSchema().$ref(AnnotationsUtils.COMPONENTS_REF + "Links"));
}
});
//adds the missing Links schema
linksCustomizer.customise(openApi);
};
}
To Reproduce
Generate an OpenAPI spec including entities manages through Spring DATA REST repositories, using latest versions of Spring Boot (3.1.3), Spring Data (2023.0.2), SpringDoc (2.2.0).
The generated schema for "links" properties (in collection or entity models) is like this:
"_links": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
The Link schema in itself is OK:
"Link": {
"title": "Link",
"type": "object",
"properties": {
"href": {
"type": "string"
},
"hreflang": {
"type": "string"
},
"title": {
"type": "string"
},
"type": {
"type": "string"
},
"deprecation": {
"type": "string"
},
"profile": {
"type": "string"
},
"name": {
"type": "string"
},
"templated": {
"type": "boolean"
}
}
}
Expected behavior
The generated schema for _links properties should be:
"_links" : {
"$ref" : "#/components/schemas/Links"
}
and the Links schema should exist:
"Links" : {
"type" : "object",
"additionalProperties" : {
"$ref" : "#/components/schemas/Link"
}
}