Я работаю с проектом Spring Data MongoDB, который экспортирует свои конечные точки через Spring Data REST. Он использует модуль springdoc-openapi-data-rest библиотеки springdoc-openapi для создания описания интерфейса OpenAPI для конечных точек Spring Data REST в проекте.
У меня есть конечная точка репозитория, которую я хотел бы исключить из сгенерированного документа OpenAPI.
@Repository
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
Если бы это был контроллер Spring MVC, подключаемый через springdoc-openapi-ui, я мог бы использовать аннотацию @Hidden из библиотеки аннотаций Swagger на контроллере. Однако это, похоже, не работает, когда надевается на класс @Repository.
@Hidden // Does not appear to have an effect
@Repository
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
Я попробовал несколько вещей, но не нашел ничего, что работало бы, кроме того, что это было похоже на хакерский обходной путь.
Как можно исключить репозиторий из сгенерированного документа OpenAPI?




Это больше относится к категории «хакерских обходных путей», но я обнаружил, что использование настроенного bean-компонента SpringRepositoryRestResourceProvider , который явно исключает данный тип сущности, работает. Определение его как bean-компонента переопределяет значение по умолчанию в 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);
}
}
}
Возможно @RepositoryRestResource(exported = false) это то, что вы ищете.
Для вашего примера это будет выглядеть следующим образом:
@Repository
@RepositoryRestResource(exported = false)
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
@Hidden // Works as of v2.0.0-M7
@Repository
public interface ExcludeMeRepository extends
PagingAndSortingRepository<ExcludeMe, Integer> {}
Это решение делает ресурс недоступным через REST. Это не соответствует моей потребности, так как я все еще хочу, чтобы репозиторий был доступен через REST; Я просто не хочу, чтобы он отображался в документе OpenAPI, созданном приложением.