Skip to content

Commit 9fee50f

Browse files
author
bnasslahsen
committed
Solves Hateoas fields names mismatch. Fixes #401
1 parent a087eaa commit 9fee50f

File tree

5 files changed

+110
-91
lines changed

5 files changed

+110
-91
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.stream.Stream;
3737

3838
import com.fasterxml.jackson.annotation.JsonView;
39+
import io.swagger.v3.core.filter.SpecFilter;
3940
import io.swagger.v3.core.util.ReflectionUtils;
4041
import io.swagger.v3.oas.annotations.Hidden;
4142
import io.swagger.v3.oas.models.Components;
@@ -64,7 +65,7 @@
6465
import org.springframework.web.bind.annotation.RequestMethod;
6566
import org.springframework.web.method.HandlerMethod;
6667

67-
public abstract class AbstractOpenApiResource {
68+
public abstract class AbstractOpenApiResource extends SpecFilter {
6869

6970
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractOpenApiResource.class);
7071

@@ -127,6 +128,7 @@ protected synchronized OpenAPI getOpenApi() {
127128
// run the optional customisers
128129
openApiCustomisers.ifPresent(apiCustomisers -> apiCustomisers.forEach(openApiCustomiser -> openApiCustomiser.customise(openApi)));
129130
computeDone = true;
131+
this.removeBrokenReferenceDefinitions(openApi);
130132
openAPIBuilder.setCachedOpenAPI(openApi);
131133
openAPIBuilder.resetCalculatedOpenAPI();
132134
LOGGER.info("Init duration for springdoc-openapi is: {} ms",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package org.springdoc.core;
20+
21+
import javax.annotation.PostConstruct;
22+
23+
import io.swagger.v3.core.util.Json;
24+
25+
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
26+
import org.springframework.hateoas.mediatype.hal.Jackson2HalModule;
27+
28+
public class HalProvider {
29+
30+
private final RepositoryRestConfiguration repositoryRestConfiguration;
31+
32+
public HalProvider(RepositoryRestConfiguration repositoryRestConfiguration) {
33+
this.repositoryRestConfiguration = repositoryRestConfiguration;
34+
}
35+
36+
@PostConstruct
37+
private void init(){
38+
if(repositoryRestConfiguration.useHalAsDefaultJsonMediaType())
39+
Json.mapper().registerModule(new Jackson2HalModule());
40+
}
41+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2424
import org.springframework.context.annotation.Bean;
2525
import org.springframework.context.annotation.Configuration;
26+
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
2627

2728
import static org.springdoc.core.Constants.SPRINGDOC_ENABLED;
2829

@@ -35,4 +36,8 @@ PageableSupportConverter pageableSupportConverter() {
3536
return new PageableSupportConverter();
3637
}
3738

39+
@Bean
40+
public HalProvider halProvider(RepositoryRestConfiguration repositoryRestConfiguration) {
41+
return new HalProvider(repositoryRestConfiguration);
42+
}
3843
}

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

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -78,32 +78,6 @@
7878
},
7979
"components": {
8080
"schemas": {
81-
"Pageable": {
82-
"required": [
83-
"page",
84-
"size"
85-
],
86-
"type": "object",
87-
"properties": {
88-
"page": {
89-
"minimum": 0,
90-
"type": "integer",
91-
"format": "int32"
92-
},
93-
"size": {
94-
"maximum": 2000,
95-
"minimum": 1,
96-
"type": "integer",
97-
"format": "int32"
98-
},
99-
"sort": {
100-
"type": "array",
101-
"items": {
102-
"type": "string"
103-
}
104-
}
105-
}
106-
},
10781
"PersonDTO": {
10882
"type": "object",
10983
"properties": {

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

Lines changed: 61 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,30 @@
1111
}
1212
],
1313
"paths": {
14-
"/employees/{id}": {
14+
"/employees": {
1515
"get": {
1616
"tags": [
1717
"employee-controller"
1818
],
19-
"operationId": "findOne",
20-
"parameters": [
21-
{
22-
"name": "id",
23-
"in": "path",
24-
"required": true,
25-
"schema": {
26-
"type": "integer",
27-
"format": "int64"
28-
}
29-
}
30-
],
19+
"operationId": "findAll",
3120
"responses": {
3221
"200": {
3322
"description": "default response",
3423
"content": {
3524
"*/*": {
3625
"schema": {
37-
"$ref": "#/components/schemas/EntityModelEmployee"
26+
"$ref": "#/components/schemas/CollectionModelEntityModelEmployee"
3827
}
3928
}
4029
}
4130
}
4231
}
4332
},
44-
"put": {
33+
"post": {
4534
"tags": [
4635
"employee-controller"
4736
],
48-
"operationId": "updateEmployee",
49-
"parameters": [
50-
{
51-
"name": "id",
52-
"in": "path",
53-
"required": true,
54-
"schema": {
55-
"type": "integer",
56-
"format": "int64"
57-
}
58-
}
59-
],
37+
"operationId": "newEmployee",
6038
"requestBody": {
6139
"content": {
6240
"application/json": {
@@ -68,35 +46,64 @@
6846
},
6947
"responses": {
7048
"200": {
71-
"description": "default response"
49+
"description": "default response",
50+
"content": {
51+
"*/*": {
52+
"schema": {
53+
"$ref": "#/components/schemas/EntityModelEmployee"
54+
}
55+
}
56+
}
7257
}
7358
}
7459
}
7560
},
76-
"/employees": {
61+
"/employees/{id}": {
7762
"get": {
7863
"tags": [
7964
"employee-controller"
8065
],
81-
"operationId": "findAll",
66+
"operationId": "findOne",
67+
"parameters": [
68+
{
69+
"name": "id",
70+
"in": "path",
71+
"required": true,
72+
"schema": {
73+
"type": "integer",
74+
"format": "int64"
75+
}
76+
}
77+
],
8278
"responses": {
8379
"200": {
8480
"description": "default response",
8581
"content": {
8682
"*/*": {
8783
"schema": {
88-
"$ref": "#/components/schemas/CollectionModelEntityModelEmployee"
84+
"$ref": "#/components/schemas/EntityModelEmployee"
8985
}
9086
}
9187
}
9288
}
9389
}
9490
},
95-
"post": {
91+
"put": {
9692
"tags": [
9793
"employee-controller"
9894
],
99-
"operationId": "newEmployee",
95+
"operationId": "updateEmployee",
96+
"parameters": [
97+
{
98+
"name": "id",
99+
"in": "path",
100+
"required": true,
101+
"schema": {
102+
"type": "integer",
103+
"format": "int64"
104+
}
105+
}
106+
],
100107
"requestBody": {
101108
"content": {
102109
"application/json": {
@@ -108,21 +115,31 @@
108115
},
109116
"responses": {
110117
"200": {
111-
"description": "default response",
112-
"content": {
113-
"*/*": {
114-
"schema": {
115-
"$ref": "#/components/schemas/EntityModelEmployee"
116-
}
117-
}
118-
}
118+
"description": "default response"
119119
}
120120
}
121121
}
122122
}
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+
},
126143
"Employee": {
127144
"type": "object",
128145
"properties": {
@@ -157,7 +174,7 @@
157174
"role": {
158175
"type": "string"
159176
},
160-
"links": {
177+
"_links": {
161178
"type": "array",
162179
"items": {
163180
"$ref": "#/components/schemas/Link"
@@ -168,18 +185,12 @@
168185
"Link": {
169186
"type": "object",
170187
"properties": {
171-
"rel": {
172-
"type": "string"
173-
},
174188
"href": {
175189
"type": "string"
176190
},
177191
"hreflang": {
178192
"type": "string"
179193
},
180-
"media": {
181-
"type": "string"
182-
},
183194
"title": {
184195
"type": "string"
185196
},
@@ -194,23 +205,9 @@
194205
},
195206
"name": {
196207
"type": "string"
197-
}
198-
}
199-
},
200-
"CollectionModelEntityModelEmployee": {
201-
"type": "object",
202-
"properties": {
203-
"links": {
204-
"type": "array",
205-
"items": {
206-
"$ref": "#/components/schemas/Link"
207-
}
208208
},
209-
"content": {
210-
"type": "array",
211-
"items": {
212-
"$ref": "#/components/schemas/EntityModelEmployee"
213-
}
209+
"templated": {
210+
"type": "boolean"
214211
}
215212
}
216213
}

0 commit comments

Comments
 (0)