Reputation: 21347
I am working with a Spring Data MongoDB project which exports its endpoints via Spring Data REST. It uses the springdoc-openapi-data-rest
module of the springdoc-openapi library to generate an OpenAPI interface description for the Spring Data REST endpoints in project.
I have a repository endpoint that I would like to exclude from the generated OpenAPI document.
@Repository
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
If this were a Spring MVC controller being included via springdoc-openapi-ui
, I could use the @Hidden
annotation from the Swagger Annotations library on the controller. However, this does not appear to work when put on a @Repository
class.
@Hidden // Does not appear to have an effect
@Repository
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
I have tried out a few things, but haven't found anything that works that doesn't also feel like a hacky workaround.
How can a respository be excluded from the generated OpenAPI document?
Upvotes: 6
Views: 10818
Reputation: 21347
The @Hidden
annotation is now supported as of the v2.0.0 version of springdoc-openapi. This change was added per springdoc-openapi#1881.
@Hidden // Works as of v2.0.0
@Repository
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
Upvotes: 10
Reputation: 1
Maybe @RepositoryRestResource(exported = false)
is, what you are looking for.
For your example, this would look as follows:
@Repository
@RepositoryRestResource(exported = false)
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
See Spring Data REST Reference Guide - Hiding Certain Repositories, Query Methods, or Fields
Upvotes: 0
Reputation: 21347
This is more in the "hacky workaround" category, but I found that using a customized SpringRepositoryRestResourceProvider
bean which explicitly excludes the given entity type appears to work. Defining it as a bean overrides the default one in SpringDocDataRestConfiguration
.
@Configuration
public class OpenApiConfig {
@Bean
public SpringRepositoryRestResourceProvider springRepositoryRestResourceProvider(
ResourceMappings mappings, ListableBeanFactory listableBeanFactory,
Associations associations, ApplicationContext applicationContext,
DataRestRouterOperationService dataRestRouterOperationService,
PersistentEntities persistentEntities, ObjectMapper mapper,
SpringDocDataRestUtils springDocDataRestUtils) {
Repositories filteredRepositories =
new RepositoriesWithoutExcludeMe(listableBeanFactory);
return new SpringRepositoryRestResourceProvider(
mappings, filteredRepositories, associations,
applicationContext, dataRestRouterOperationService,
persistentEntities, mapper, springDocDataRestUtils);
}
private static class RepositoriesWithoutExcludeMe extends Repositories {
RepositoriesWithoutExcludeMe(ListableBeanFactory factory) {
super(factory);
}
@Override
public boolean hasRepositoryFor(Class<?> domainClass) {
return !isExcludeMe(domainClass)
&& super.hasRepositoryFor(domainClass);
}
@Override
public Optional<Object> getRepositoryFor(Class<?> domainClass) {
return optional(domainClass, super::getRepositoryFor);
}
@Override
public <T, S> EntityInformation<T, S> getEntityInformationFor(
Class<?> domainClass) {
return nullable(domainClass, super::getEntityInformationFor);
}
@Override
public Optional<RepositoryInformation> getRepositoryInformationFor(
Class<?> domainClass) {
return optional(domainClass, super::getRepositoryInformationFor);
}
@Override
public RepositoryInformation getRequiredRepositoryInformation(
Class<?> domainType) {
if (isExcludeMe(domainType)) {
throw new IllegalArgumentException(
"No required RepositoryInformation found for domain type "
+ domainType.getName());
} else {
return nullable(domainType,
super::getRequiredRepositoryInformation);
}
}
@Override
public Optional<RepositoryInformation> getRepositoryInformation(
Class<?> repositoryInterface) {
return optional(repositoryInterface,
super::getRepositoryInformation);
}
@Override
public PersistentEntity<?, ?> getPersistentEntity(
Class<?> domainClass) {
return nullable(domainClass, super::getPersistentEntity);
}
@Override
public List<QueryMethod> getQueryMethodsFor(Class<?> domainClass) {
return isExcludeMe(domainClass)
? List.of() : super.getQueryMethodsFor(domainClass);
}
@Override
public Iterator<Class<?>> iterator() {
return Iterators.filter(super.iterator(), c -> !isExcludeMe(c));
}
private static boolean isExcludeMe(Class<?> domainClass) {
return ExcludeMe.class.isAssignableFrom(domainClass);
}
private <C extends Class<?>, R> Optional<R> optional(
C domainClass, Function<C, Optional<R>> function) {
return isExcludeMe(domainClass)
? Optional.empty() : function.apply(domainClass);
}
private <C extends Class<?>, R> R nullable(
C domainClass, Function<C, R> function) {
return isExcludeMe(domainClass)
? null : function.apply(domainClass);
}
}
}
Upvotes: 0