Skip to content

Commit 653f2ee

Browse files
committed
Spring Data Rest: Wrong response schema after POST,PUT,PATCH operations. fixes #1068
1 parent 362e2f9 commit 653f2ee

File tree

9 files changed

+188
-219
lines changed

9 files changed

+188
-219
lines changed

springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/SpringRepositoryRestResourceProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public class SpringRepositoryRestResourceProvider implements RepositoryRestResou
8484
/**
8585
* The constant REPOSITORY_ENTITY_CONTROLLER.
8686
*/
87-
private static final String REPOSITORY_ENTITY_CONTROLLER = SPRING_DATA_REST_PACKAGE + ".webmvc.RepositoryEntityController";
87+
public static final String REPOSITORY_ENTITY_CONTROLLER = SPRING_DATA_REST_PACKAGE + ".webmvc.RepositoryEntityController";
8888

8989
/**
9090
* The constant REPOSITORY_SEARCH_CONTROLLER.

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

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.lang.reflect.ParameterizedType;
2727
import java.lang.reflect.Type;
2828
import java.lang.reflect.WildcardType;
29+
import java.util.Arrays;
2930
import java.util.Objects;
3031
import java.util.Set;
3132

@@ -37,6 +38,7 @@
3738
import org.springdoc.core.GenericResponseService;
3839
import org.springdoc.core.MethodAttributes;
3940
import org.springdoc.core.ReturnTypeParser;
41+
import org.springdoc.data.rest.SpringRepositoryRestResourceProvider;
4042

4143
import org.springframework.core.MethodParameter;
4244
import org.springframework.core.ResolvableType;
@@ -64,6 +66,11 @@ public class DataRestResponseService {
6466
*/
6567
private GenericResponseService genericResponseService;
6668

69+
/**
70+
* The constant requestMethodsEntityModel.
71+
*/
72+
private static final RequestMethod[] requestMethodsEntityModel = { RequestMethod.PATCH, RequestMethod.POST, RequestMethod.PUT };
73+
6774
/**
6875
* Instantiates a new Data rest response builder.
6976
*
@@ -120,8 +127,7 @@ public void buildSearchResponse(Operation operation, HandlerMethod handlerMethod
120127
public void buildEntityResponse(Operation operation, HandlerMethod handlerMethod, OpenAPI openAPI, RequestMethod requestMethod,
121128
String operationPath, Class<?> domainType, MethodAttributes methodAttributes) {
122129
MethodParameter methodParameterReturn = handlerMethod.getReturnType();
123-
Type returnType = ReturnTypeParser.resolveType(methodParameterReturn.getGenericParameterType(), methodParameterReturn.getContainingClass());
124-
returnType = getType(returnType, domainType);
130+
Type returnType = getType(methodParameterReturn, domainType, requestMethod);
125131
ApiResponses apiResponses = new ApiResponses();
126132
ApiResponse apiResponse = new ApiResponse();
127133
Content content = genericResponseService.buildContent(openAPI.getComponents(), methodParameterReturn.getParameterAnnotations(), methodAttributes.getMethodProduces(), null, returnType);
@@ -195,11 +201,13 @@ else if (ClassUtils.isPrimitiveOrWrapper(methodResourceMapping.getReturnedDomain
195201
/**
196202
* Gets type.
197203
*
198-
* @param returnType the return type
204+
* @param methodParameterReturn the method parameter return
199205
* @param domainType the domain type
206+
* @param requestMethod the request method
200207
* @return the type
201208
*/
202-
private Type getType(Type returnType, Class<?> domainType) {
209+
private Type getType(MethodParameter methodParameterReturn, Class<?> domainType, RequestMethod requestMethod) {
210+
Type returnType = ReturnTypeParser.resolveType(methodParameterReturn.getGenericParameterType(), methodParameterReturn.getContainingClass());
203211
if (returnType instanceof ParameterizedType) {
204212
ParameterizedType parameterizedType = (ParameterizedType) returnType;
205213
if ((ResponseEntity.class.equals(parameterizedType.getRawType()))) {
@@ -210,7 +218,8 @@ else if (parameterizedType.getActualTypeArguments()[0] instanceof ParameterizedT
210218
ParameterizedType parameterizedType1 = (ParameterizedType) parameterizedType.getActualTypeArguments()[0];
211219
Class<?> rawType = ResolvableType.forType(parameterizedType1.getRawType()).getRawClass();
212220
if (rawType != null && rawType.isAssignableFrom(RepresentationModel.class)) {
213-
return resolveGenericType(ResponseEntity.class, RepresentationModel.class, domainType);
221+
Class<?> type = findType(methodParameterReturn, requestMethod);
222+
return resolveGenericType(ResponseEntity.class, type, domainType);
214223
}
215224
else if (EntityModel.class.equals(parameterizedType1.getRawType())) {
216225
return resolveGenericType(ResponseEntity.class, EntityModel.class, domainType);
@@ -221,7 +230,8 @@ else if (parameterizedType.getActualTypeArguments()[0] instanceof WildcardType)
221230
if (wildcardType.getUpperBounds()[0] instanceof ParameterizedType) {
222231
ParameterizedType wildcardTypeUpperBound = (ParameterizedType) wildcardType.getUpperBounds()[0];
223232
if (RepresentationModel.class.equals(wildcardTypeUpperBound.getRawType())) {
224-
return resolveGenericType(ResponseEntity.class, RepresentationModel.class, domainType);
233+
Class<?> type = findType(methodParameterReturn, requestMethod);
234+
return resolveGenericType(ResponseEntity.class, type, domainType);
225235
}
226236
}
227237
}
@@ -241,6 +251,21 @@ else if ((CollectionModel.class.equals(parameterizedType.getRawType())
241251
return returnType;
242252
}
243253

254+
/**
255+
* Find type class.
256+
*
257+
* @param methodParameterReturn the method parameter return
258+
* @param requestMethod the request method
259+
* @return the class
260+
*/
261+
private Class findType(MethodParameter methodParameterReturn, RequestMethod requestMethod) {
262+
if (SpringRepositoryRestResourceProvider.REPOSITORY_ENTITY_CONTROLLER.equals(methodParameterReturn.getContainingClass().getCanonicalName())
263+
&& Arrays.stream(requestMethodsEntityModel).anyMatch(requestMethod::equals))
264+
return EntityModel.class;
265+
else
266+
return RepresentationModel.class;
267+
}
268+
244269
/**
245270
* Resolve generic type type.
246271
*

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

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"content": {
6363
"application/hal+json": {
6464
"schema": {
65-
"$ref": "#/components/schemas/RepresentationModelAccount"
65+
"$ref": "#/components/schemas/EntityModelAccount"
6666
}
6767
}
6868
}
@@ -166,7 +166,7 @@
166166
"content": {
167167
"application/hal+json": {
168168
"schema": {
169-
"$ref": "#/components/schemas/RepresentationModelAccount"
169+
"$ref": "#/components/schemas/EntityModelAccount"
170170
}
171171
}
172172
}
@@ -176,7 +176,7 @@
176176
"content": {
177177
"application/hal+json": {
178178
"schema": {
179-
"$ref": "#/components/schemas/RepresentationModelAccount"
179+
"$ref": "#/components/schemas/EntityModelAccount"
180180
}
181181
}
182182
}
@@ -242,7 +242,7 @@
242242
"content": {
243243
"application/hal+json": {
244244
"schema": {
245-
"$ref": "#/components/schemas/RepresentationModelAccount"
245+
"$ref": "#/components/schemas/EntityModelAccount"
246246
}
247247
}
248248
}
@@ -555,7 +555,7 @@
555555
"content": {
556556
"application/hal+json": {
557557
"schema": {
558-
"$ref": "#/components/schemas/RepresentationModelCustomer"
558+
"$ref": "#/components/schemas/EntityModelCustomer"
559559
}
560560
}
561561
}
@@ -693,7 +693,7 @@
693693
"content": {
694694
"application/hal+json": {
695695
"schema": {
696-
"$ref": "#/components/schemas/RepresentationModelCustomer"
696+
"$ref": "#/components/schemas/EntityModelCustomer"
697697
}
698698
}
699699
}
@@ -703,7 +703,7 @@
703703
"content": {
704704
"application/hal+json": {
705705
"schema": {
706-
"$ref": "#/components/schemas/RepresentationModelCustomer"
706+
"$ref": "#/components/schemas/EntityModelCustomer"
707707
}
708708
}
709709
}
@@ -744,7 +744,7 @@
744744
"content": {
745745
"application/hal+json": {
746746
"schema": {
747-
"$ref": "#/components/schemas/RepresentationModelCustomer"
747+
"$ref": "#/components/schemas/EntityModelCustomer"
748748
}
749749
}
750750
}
@@ -968,14 +968,6 @@
968968
}
969969
}
970970
},
971-
"RepresentationModelAccount": {
972-
"type": "object",
973-
"properties": {
974-
"_links": {
975-
"$ref": "#/components/schemas/Links"
976-
}
977-
}
978-
},
979971
"EntityModelAccount": {
980972
"type": "object",
981973
"properties": {
@@ -995,6 +987,14 @@
995987
}
996988
}
997989
},
990+
"RepresentationModelAccount": {
991+
"type": "object",
992+
"properties": {
993+
"_links": {
994+
"$ref": "#/components/schemas/Links"
995+
}
996+
}
997+
},
998998
"CollectionModelObject": {
999999
"type": "object",
10001000
"properties": {
@@ -1033,14 +1033,6 @@
10331033
}
10341034
}
10351035
},
1036-
"RepresentationModelCustomer": {
1037-
"type": "object",
1038-
"properties": {
1039-
"_links": {
1040-
"$ref": "#/components/schemas/Links"
1041-
}
1042-
}
1043-
},
10441036
"EntityModelCustomer": {
10451037
"type": "object",
10461038
"properties": {

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

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
"content": {
9999
"application/hal+json": {
100100
"schema": {
101-
"$ref": "#/components/schemas/RepresentationModelPerson"
101+
"$ref": "#/components/schemas/EntityModelPerson"
102102
}
103103
}
104104
}
@@ -202,7 +202,7 @@
202202
"content": {
203203
"application/hal+json": {
204204
"schema": {
205-
"$ref": "#/components/schemas/RepresentationModelPerson"
205+
"$ref": "#/components/schemas/EntityModelPerson"
206206
}
207207
}
208208
}
@@ -212,7 +212,7 @@
212212
"content": {
213213
"application/hal+json": {
214214
"schema": {
215-
"$ref": "#/components/schemas/RepresentationModelPerson"
215+
"$ref": "#/components/schemas/EntityModelPerson"
216216
}
217217
}
218218
}
@@ -278,7 +278,7 @@
278278
"content": {
279279
"application/hal+json": {
280280
"schema": {
281-
"$ref": "#/components/schemas/RepresentationModelPerson"
281+
"$ref": "#/components/schemas/EntityModelPerson"
282282
}
283283
}
284284
}
@@ -422,6 +422,17 @@
422422
}
423423
}
424424
},
425+
"Person": {
426+
"type": "object",
427+
"properties": {
428+
"firstName": {
429+
"type": "string"
430+
},
431+
"lastName": {
432+
"type": "string"
433+
}
434+
}
435+
},
425436
"CollectionModelPerson": {
426437
"type": "object",
427438
"properties": {
@@ -441,25 +452,6 @@
441452
}
442453
}
443454
},
444-
"Person": {
445-
"type": "object",
446-
"properties": {
447-
"firstName": {
448-
"type": "string"
449-
},
450-
"lastName": {
451-
"type": "string"
452-
}
453-
}
454-
},
455-
"RepresentationModelPerson": {
456-
"type": "object",
457-
"properties": {
458-
"_links": {
459-
"$ref": "#/components/schemas/Links"
460-
}
461-
}
462-
},
463455
"EntityModelPerson": {
464456
"type": "object",
465457
"properties": {

0 commit comments

Comments
 (0)