Skip to content

Commit 8adb767

Browse files
committed
Spring Data Rest: No model for Paged Collection. fixes #1083
1 parent 4cf7d45 commit 8adb767

File tree

7 files changed

+152
-24
lines changed

7 files changed

+152
-24
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ private Operation buildEntityOperation(HandlerMethod handlerMethod, DataRestRepo
155155
domainType = dataRestRepository.getDomainType();
156156
Operation operation = initOperation(handlerMethod, domainType, requestMethod);
157157
dataRestRequestService.buildParameters(domainType, openAPI, handlerMethod, requestMethod, methodAttributes, operation, resourceMetadata);
158-
dataRestResponseService.buildEntityResponse(operation, handlerMethod, openAPI, requestMethod, operationPath, domainType, methodAttributes, dataRestRepository);
158+
dataRestResponseService.buildEntityResponse(operation, handlerMethod, openAPI, requestMethod, operationPath, domainType, methodAttributes, dataRestRepository, resourceMetadata);
159159
tagsBuilder.buildEntityTags(operation, handlerMethod, dataRestRepository);
160160
if (domainType != null)
161161
addOperationDescription(operation, requestMethod, domainType.getSimpleName().toLowerCase(), dataRestRepository);

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.springframework.core.MethodParameter;
4747
import org.springframework.core.ResolvableType;
4848
import org.springframework.data.rest.core.mapping.MethodResourceMapping;
49+
import org.springframework.data.rest.core.mapping.ResourceMetadata;
4950
import org.springframework.data.rest.webmvc.RestMediaTypes;
5051
import org.springframework.hateoas.CollectionModel;
5152
import org.springframework.hateoas.EntityModel;
@@ -120,7 +121,6 @@ public void buildSearchResponse(Operation operation, HandlerMethod handlerMethod
120121

121122
/**
122123
* Build entity response.
123-
*
124124
* @param operation the operation
125125
* @param handlerMethod the handler method
126126
* @param openAPI the open api
@@ -129,11 +129,12 @@ public void buildSearchResponse(Operation operation, HandlerMethod handlerMethod
129129
* @param domainType the domain type
130130
* @param methodAttributes the method attributes
131131
* @param dataRestRepository the data rest repository
132+
* @param resourceMetadata the resource metadata
132133
*/
133134
public void buildEntityResponse(Operation operation, HandlerMethod handlerMethod, OpenAPI openAPI, RequestMethod requestMethod,
134-
String operationPath, Class<?> domainType, MethodAttributes methodAttributes, DataRestRepository dataRestRepository) {
135+
String operationPath, Class<?> domainType, MethodAttributes methodAttributes, DataRestRepository dataRestRepository, ResourceMetadata resourceMetadata) {
135136
MethodParameter methodParameterReturn = handlerMethod.getReturnType();
136-
Type returnType = getType(methodParameterReturn, domainType, requestMethod, dataRestRepository);
137+
Type returnType = getType(methodParameterReturn, domainType, requestMethod, dataRestRepository, resourceMetadata);
137138
ApiResponses apiResponses = new ApiResponses();
138139
ApiResponse apiResponse = new ApiResponse();
139140
Content content = genericResponseService.buildContent(openAPI.getComponents(), methodParameterReturn.getParameterAnnotations(), methodAttributes.getMethodProduces(), null, returnType);
@@ -213,9 +214,10 @@ else if (ClassUtils.isPrimitiveOrWrapper(methodResourceMapping.getReturnedDomain
213214
* @param domainType the domain type
214215
* @param requestMethod the request method
215216
* @param dataRestRepository the data rest repository
217+
* @param resourceMetadata the resource metadata
216218
* @return the type
217219
*/
218-
private Type getType(MethodParameter methodParameterReturn, Class<?> domainType, RequestMethod requestMethod, DataRestRepository dataRestRepository) {
220+
private Type getType(MethodParameter methodParameterReturn, Class<?> domainType, RequestMethod requestMethod, DataRestRepository dataRestRepository, ResourceMetadata resourceMetadata) {
219221
Type returnType = ReturnTypeParser.resolveType(methodParameterReturn.getGenericParameterType(), methodParameterReturn.getContainingClass());
220222
Class returnedEntityType = domainType;
221223

@@ -259,7 +261,10 @@ else if ((HttpEntity.class.equals(parameterizedType.getRawType())
259261
}
260262
else if ((CollectionModel.class.equals(parameterizedType.getRawType())
261263
&& Object.class.equals(parameterizedType.getActualTypeArguments()[0]))) {
262-
return resolveGenericType(CollectionModel.class, EntityModel.class, returnedEntityType);
264+
if (resourceMetadata.isPagingResource())
265+
return resolveGenericType(PagedModel.class, EntityModel.class, returnedEntityType);
266+
else
267+
return resolveGenericType(CollectionModel.class, EntityModel.class, returnedEntityType);
263268
}
264269
}
265270
return returnType;

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
"content": {
6161
"application/hal+json": {
6262
"schema": {
63-
"$ref": "#/components/schemas/CollectionModelEntityModelPerson"
63+
"$ref": "#/components/schemas/PagedModelEntityModelPerson"
6464
}
6565
},
6666
"application/x-spring-data-compact+json": {
6767
"schema": {
68-
"$ref": "#/components/schemas/CollectionModelEntityModelPerson"
68+
"$ref": "#/components/schemas/PagedModelEntityModelPerson"
6969
}
7070
},
7171
"text/uri-list": {
@@ -450,7 +450,28 @@
450450
}
451451
}
452452
},
453-
"CollectionModelEntityModelPerson": {
453+
"PageMetadata": {
454+
"type": "object",
455+
"properties": {
456+
"size": {
457+
"type": "integer",
458+
"format": "int64"
459+
},
460+
"totalElements": {
461+
"type": "integer",
462+
"format": "int64"
463+
},
464+
"totalPages": {
465+
"type": "integer",
466+
"format": "int64"
467+
},
468+
"number": {
469+
"type": "integer",
470+
"format": "int64"
471+
}
472+
}
473+
},
474+
"PagedModelEntityModelPerson": {
454475
"type": "object",
455476
"properties": {
456477
"_embedded": {
@@ -466,6 +487,9 @@
466487
},
467488
"_links": {
468489
"$ref": "#/components/schemas/Links"
490+
},
491+
"page": {
492+
"$ref": "#/components/schemas/PageMetadata"
469493
}
470494
}
471495
},

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

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
"content": {
6161
"application/hal+json": {
6262
"schema": {
63-
"$ref": "#/components/schemas/CollectionModelEntityModelChildProperty"
63+
"$ref": "#/components/schemas/PagedModelEntityModelChildProperty"
6464
}
6565
},
6666
"application/x-spring-data-compact+json": {
6767
"schema": {
68-
"$ref": "#/components/schemas/CollectionModelEntityModelChildProperty"
68+
"$ref": "#/components/schemas/PagedModelEntityModelChildProperty"
6969
}
7070
},
7171
"text/uri-list": {
@@ -389,12 +389,12 @@
389389
"content": {
390390
"application/hal+json": {
391391
"schema": {
392-
"$ref": "#/components/schemas/CollectionModelEntityModelProperty"
392+
"$ref": "#/components/schemas/PagedModelEntityModelProperty"
393393
}
394394
},
395395
"application/x-spring-data-compact+json": {
396396
"schema": {
397-
"$ref": "#/components/schemas/CollectionModelEntityModelProperty"
397+
"$ref": "#/components/schemas/PagedModelEntityModelProperty"
398398
}
399399
},
400400
"text/uri-list": {
@@ -952,7 +952,28 @@
952952
}
953953
}
954954
},
955-
"CollectionModelEntityModelChildProperty": {
955+
"PageMetadata": {
956+
"type": "object",
957+
"properties": {
958+
"size": {
959+
"type": "integer",
960+
"format": "int64"
961+
},
962+
"totalElements": {
963+
"type": "integer",
964+
"format": "int64"
965+
},
966+
"totalPages": {
967+
"type": "integer",
968+
"format": "int64"
969+
},
970+
"number": {
971+
"type": "integer",
972+
"format": "int64"
973+
}
974+
}
975+
},
976+
"PagedModelEntityModelChildProperty": {
956977
"type": "object",
957978
"properties": {
958979
"_embedded": {
@@ -968,6 +989,9 @@
968989
},
969990
"_links": {
970991
"$ref": "#/components/schemas/Links"
992+
},
993+
"page": {
994+
"$ref": "#/components/schemas/PageMetadata"
971995
}
972996
}
973997
},
@@ -1004,7 +1028,7 @@
10041028
}
10051029
}
10061030
},
1007-
"CollectionModelEntityModelProperty": {
1031+
"PagedModelEntityModelProperty": {
10081032
"type": "object",
10091033
"properties": {
10101034
"_embedded": {
@@ -1020,6 +1044,9 @@
10201044
},
10211045
"_links": {
10221046
"$ref": "#/components/schemas/Links"
1047+
},
1048+
"page": {
1049+
"$ref": "#/components/schemas/PageMetadata"
10231050
}
10241051
}
10251052
},

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@
5959
"content": {
6060
"application/hal+json": {
6161
"schema": {
62-
"$ref": "#/components/schemas/CollectionModelEntityModelBank"
62+
"$ref": "#/components/schemas/PagedModelEntityModelBank"
6363
}
6464
},
6565
"application/x-spring-data-compact+json": {
6666
"schema": {
67-
"$ref": "#/components/schemas/CollectionModelEntityModelBank"
67+
"$ref": "#/components/schemas/PagedModelEntityModelBank"
6868
}
6969
},
7070
"text/uri-list": {
@@ -490,7 +490,28 @@
490490
}
491491
}
492492
},
493-
"CollectionModelEntityModelBank": {
493+
"PageMetadata": {
494+
"type": "object",
495+
"properties": {
496+
"size": {
497+
"type": "integer",
498+
"format": "int64"
499+
},
500+
"totalElements": {
501+
"type": "integer",
502+
"format": "int64"
503+
},
504+
"totalPages": {
505+
"type": "integer",
506+
"format": "int64"
507+
},
508+
"number": {
509+
"type": "integer",
510+
"format": "int64"
511+
}
512+
}
513+
},
514+
"PagedModelEntityModelBank": {
494515
"type": "object",
495516
"properties": {
496517
"_embedded": {
@@ -506,6 +527,9 @@
506527
},
507528
"_links": {
508529
"$ref": "#/components/schemas/Links"
530+
},
531+
"page": {
532+
"$ref": "#/components/schemas/PageMetadata"
509533
}
510534
}
511535
},

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
"content": {
6161
"application/hal+json": {
6262
"schema": {
63-
"$ref": "#/components/schemas/CollectionModelEntityModelPerson"
63+
"$ref": "#/components/schemas/PagedModelEntityModelPerson"
6464
}
6565
},
6666
"application/x-spring-data-compact+json": {
6767
"schema": {
68-
"$ref": "#/components/schemas/CollectionModelEntityModelPerson"
68+
"$ref": "#/components/schemas/PagedModelEntityModelPerson"
6969
}
7070
},
7171
"text/uri-list": {
@@ -537,7 +537,28 @@
537537
}
538538
}
539539
},
540-
"CollectionModelEntityModelPerson": {
540+
"PageMetadata": {
541+
"type": "object",
542+
"properties": {
543+
"size": {
544+
"type": "integer",
545+
"format": "int64"
546+
},
547+
"totalElements": {
548+
"type": "integer",
549+
"format": "int64"
550+
},
551+
"totalPages": {
552+
"type": "integer",
553+
"format": "int64"
554+
},
555+
"number": {
556+
"type": "integer",
557+
"format": "int64"
558+
}
559+
}
560+
},
561+
"PagedModelEntityModelPerson": {
541562
"type": "object",
542563
"properties": {
543564
"_embedded": {
@@ -553,6 +574,9 @@
553574
},
554575
"_links": {
555576
"$ref": "#/components/schemas/Links"
577+
},
578+
"page": {
579+
"$ref": "#/components/schemas/PageMetadata"
556580
}
557581
}
558582
},

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

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@
6060
"content": {
6161
"application/hal+json": {
6262
"schema": {
63-
"$ref": "#/components/schemas/CollectionModelEntityModelPerson"
63+
"$ref": "#/components/schemas/PagedModelEntityModelPerson"
6464
}
6565
},
6666
"application/x-spring-data-compact+json": {
6767
"schema": {
68-
"$ref": "#/components/schemas/CollectionModelEntityModelPerson"
68+
"$ref": "#/components/schemas/PagedModelEntityModelPerson"
6969
}
7070
},
7171
"text/uri-list": {
@@ -438,7 +438,28 @@
438438
}
439439
}
440440
},
441-
"CollectionModelEntityModelPerson": {
441+
"PageMetadata": {
442+
"type": "object",
443+
"properties": {
444+
"size": {
445+
"type": "integer",
446+
"format": "int64"
447+
},
448+
"totalElements": {
449+
"type": "integer",
450+
"format": "int64"
451+
},
452+
"totalPages": {
453+
"type": "integer",
454+
"format": "int64"
455+
},
456+
"number": {
457+
"type": "integer",
458+
"format": "int64"
459+
}
460+
}
461+
},
462+
"PagedModelEntityModelPerson": {
442463
"type": "object",
443464
"properties": {
444465
"_embedded": {
@@ -454,6 +475,9 @@
454475
},
455476
"_links": {
456477
"$ref": "#/components/schemas/Links"
478+
},
479+
"page": {
480+
"$ref": "#/components/schemas/PageMetadata"
457481
}
458482
}
459483
},

0 commit comments

Comments
 (0)