diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java index b878c64f4..37114632f 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java @@ -55,6 +55,7 @@ import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.SimpleAssociationHandler; import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.core.mapping.ResourceMetadata; @@ -133,7 +134,7 @@ public void customise(OpenAPI openAPI, ResourceMappings mappings, PersistentEnti entityInfo.setAssociationsFields(associationsFields); entityInoMap.put(domainType.getSimpleName(), entityInfo); } - + openAPI.getPaths().entrySet().stream() .forEach(stringPathItemEntry -> { PathItem pathItem = stringPathItemEntry.getValue(); @@ -417,9 +418,11 @@ private List getAssociationsFields(ResourceMetadata List associationsFields = new ArrayList<>(); entity.doWithAssociations((SimpleAssociationHandler) association -> { PersistentProperty property = association.getInverse(); - String filedName = resourceMetadata.getMappingFor(property).getRel().value(); - associationsFields.add(filedName); - }); + if (isAssociationExported(property)) { + String filedName = resourceMetadata.getMappingFor(property).getRel().value(); + associationsFields.add(filedName); + } + }); return associationsFields; } @@ -438,13 +441,31 @@ private List getIgnoredFields(ResourceMetadata ignoredFields.add(idField); entity.doWithAssociations((SimpleAssociationHandler) association -> { PersistentProperty property = association.getInverse(); - String filedName = resourceMetadata.getMappingFor(property).getRel().value(); - ignoredFields.add(filedName); - }); + if (isAssociationExported(property)) { + String filedName = resourceMetadata.getMappingFor(property).getRel().value(); + ignoredFields.add(filedName); + } + }); } return ignoredFields; } + /** + * Indicates if an association is exported. If not, it should be included in response schema. + * + * @param associationProperty the property to check + * @return true if a field is not exported + */ + private boolean isAssociationExported(PersistentProperty associationProperty) { + try { + RestResource restResource = associationProperty.getRequiredAnnotation(RestResource.class); + return restResource.exported(); + } catch (IllegalStateException e) { + //if annotation missing, association is exported by default + return true; + } + } + /** * Build text uri content. *