Skip to content

Commit 838d558

Browse files
committed
Fixes #418 by adjusting the output for Links.
There is a custom serializer for the Links object which creates a sorted map of all links. That map is then passed to jackson for serialization, thus some manual work is needed to fix the schema.
1 parent 4475bc0 commit 838d558

File tree

3 files changed

+71
-28
lines changed

3 files changed

+71
-28
lines changed

springdoc-openapi-data-rest/src/main/java/org/springdoc/core/SpringDocDataRestConfiguration.java

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,67 @@
1818

1919
package org.springdoc.core;
2020

21+
import com.fasterxml.jackson.core.JsonGenerator;
22+
import com.fasterxml.jackson.databind.SerializerProvider;
23+
import io.swagger.v3.core.converter.AnnotatedType;
24+
import io.swagger.v3.core.converter.ModelConverters;
25+
import io.swagger.v3.core.converter.ResolvedSchema;
26+
import io.swagger.v3.core.util.Json;
27+
import io.swagger.v3.oas.annotations.media.Schema;
28+
import io.swagger.v3.oas.models.media.MapSchema;
29+
import io.swagger.v3.oas.models.media.ObjectSchema;
30+
import io.swagger.v3.oas.models.media.StringSchema;
2131
import org.springdoc.core.converters.PageableSupportConverter;
22-
32+
import org.springdoc.core.customizers.OpenApiCustomiser;
2333
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2434
import org.springframework.context.annotation.Bean;
2535
import org.springframework.context.annotation.Configuration;
2636
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
37+
import org.springframework.hateoas.Link;
38+
import org.springframework.hateoas.Links;
39+
import org.springframework.hateoas.RepresentationModel;
40+
import org.springframework.hateoas.mediatype.hal.RepresentationModelMixin;
2741

2842
import static org.springdoc.core.Constants.SPRINGDOC_ENABLED;
2943

3044
@Configuration
3145
@ConditionalOnProperty(name = SPRINGDOC_ENABLED, matchIfMissing = true)
3246
public class SpringDocDataRestConfiguration {
3347

34-
@Bean
35-
PageableSupportConverter pageableSupportConverter() {
36-
return new PageableSupportConverter();
37-
}
48+
@Bean
49+
PageableSupportConverter pageableSupportConverter() {
50+
return new PageableSupportConverter();
51+
}
52+
53+
@Bean
54+
public HalProvider halProvider(RepositoryRestConfiguration repositoryRestConfiguration) {
55+
return new HalProvider(repositoryRestConfiguration);
56+
}
57+
58+
/**
59+
* Registers an OpenApiCustomiser and a jackson mixin to ensure the definition of `Links` matches the serialized
60+
* output. This is done because the customer serializer converts the data to a map before serializing it.
61+
*
62+
* @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)
63+
*/
64+
@Bean
65+
public OpenApiCustomiser linksSchemaCustomiser(RepositoryRestConfiguration repositoryRestConfiguration) {
66+
if (!repositoryRestConfiguration.useHalAsDefaultJsonMediaType()) {
67+
return openApi -> {};
68+
}
69+
Json.mapper().addMixIn(RepresentationModel.class, RepresentationModelLinksOASMixin.class);
70+
ResolvedSchema resolvedLinkSchema = ModelConverters.getInstance()
71+
.resolveAsResolvedSchema(new AnnotatedType(Link.class));
72+
return openApi -> openApi
73+
.schema("Link", resolvedLinkSchema.schema)
74+
.schema("Links", new MapSchema()
75+
.additionalProperties(new StringSchema())
76+
.additionalProperties(new ObjectSchema().$ref("#/components/schemas/Link")));
77+
}
3878

39-
@Bean
40-
public HalProvider halProvider(RepositoryRestConfiguration repositoryRestConfiguration) {
41-
return new HalProvider(repositoryRestConfiguration);
42-
}
79+
static abstract class RepresentationModelLinksOASMixin extends RepresentationModelMixin {
80+
@Override
81+
@Schema(ref = "#/components/schemas/Links")
82+
public abstract Links getLinks();
83+
}
4384
}

springdoc-openapi-data-rest/src/test/resources/results/app2.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -123,23 +123,6 @@
123123
},
124124
"components": {
125125
"schemas": {
126-
"CollectionModelEntityModelEmployee": {
127-
"type": "object",
128-
"properties": {
129-
"_embedded": {
130-
"type": "array",
131-
"items": {
132-
"$ref": "#/components/schemas/EntityModelEmployee"
133-
}
134-
},
135-
"_links": {
136-
"type": "array",
137-
"items": {
138-
"$ref": "#/components/schemas/Link"
139-
}
140-
}
141-
}
142-
},
143126
"Employee": {
144127
"type": "object",
145128
"properties": {
@@ -175,10 +158,27 @@
175158
"type": "string"
176159
},
177160
"_links": {
161+
"$ref": "#/components/schemas/Links"
162+
}
163+
}
164+
},
165+
"Links": {
166+
"type": "object",
167+
"additionalProperties": {
168+
"$ref": "#/components/schemas/Link"
169+
}
170+
},
171+
"CollectionModelEntityModelEmployee": {
172+
"type": "object",
173+
"properties": {
174+
"_embedded": {
178175
"type": "array",
179176
"items": {
180-
"$ref": "#/components/schemas/Link"
177+
"$ref": "#/components/schemas/EntityModelEmployee"
181178
}
179+
},
180+
"_links": {
181+
"$ref": "#/components/schemas/Links"
182182
}
183183
}
184184
},

springdoc-openapi-data-rest/src/test/resources/results/app3.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,7 @@
6868
}
6969
}
7070
},
71-
"components": {}
71+
"components": {
72+
"schemas": {}
73+
}
7274
}

0 commit comments

Comments
 (0)