Когда использовать @RestController против @RepositoryRestResource

87

Я рассматривал различные примеры использования Spring с REST . Наша конечная цель - HATEOAS/HALустановка Spring

Я видел два разных метода рендеринга REST в Spring

  1. Через @RestControllerконтроллер

  2. Через @RepositoryRestResourceрепозиторий

Я изо всех сил пытаюсь понять, зачем вам использовать одно вместо другого. При попытке реализовать, HALчто лучше?

Наша база данных - это Neo4j .

код
источник

Ответы:

61

Хорошо, вкратце, вы хотите использовать, @RepositoryRestResourceпоскольку это создает службу HATEOAS с Spring JPA .

Как вы можете видеть здесь, добавляя эту аннотацию и связывая ее с вашим Pojo, у вас есть полностью функциональная служба HATEOAS без необходимости реализации метода репозитория или методов службы REST.

Если вы добавите, @RestControllerто вам придется реализовать каждый метод, который вы хотите предоставить, самостоятельно, а также он не экспортирует его в формат HATEOAS .

зпонтикас
источник
7
По умолчанию Spring Data REST экспортирует ВСЕ репозитории общедоступного интерфейса верхнего уровня. Вам нужно только @RepositoryRestResource, чтобы НЕ экспортировать интерфейс или изменить детали конечной точки.
gregturn 08
4
Если вы используете RestController с Spring Data REST, вы обойдете ВСЕ, что предоставляет Spring Data REST. Чтобы закодировать пользовательский контроллер Spring MVC, который использует преобразователи сообщений REST данных Spring и т. Д., Посмотрите в BasePathAwareController.
gregturn 08
Я не думаю, что принятый ответ правильный, у @gregturn есть лучший ответ.
Марк
39

Существует третий (и четвертый) вариант, который вы не описали, а именно использование @BasePathAwareController или @RepositoryRestController, в зависимости от того, выполняете ли вы действия, зависящие от сущности, или нет.

@RepositoryRestResource используется для установки параметров в интерфейсе общедоступного репозитория - он автоматически создает конечные точки в зависимости от типа расширяемого репозитория (например, CrudRepository / PagingAndSortingRepository / и т. Д.).

@BasePathAwareController и @RepositoryRestController используются, если вы хотите вручную создать конечные точки, но хотите использовать настроенные вами конфигурации Spring Data REST.

Если вы используете @RestController, вы создадите параллельный набор конечных точек с разными параметрами конфигурации - то есть с другим конвертером сообщений, разными обработчиками ошибок и т. Д. - но они будут счастливо сосуществовать (и, вероятно, вызовут путаницу).

Конкретную документацию можно найти здесь .

Джейкоб Крид
источник
6
Я думаю, что это уже не так. Если a @RestControllerиспользует тот же путь, что и a @RepositoryRestResource, конечные точки репозитория не будут созданы.
Hubert Grzeskowiak
19

Что ж, приведенные выше ответы верны в своем контексте, но я даю вам практический пример.

Во многих сценариях в рамках API нам необходимо предоставить конечные точки для поиска объекта на основе определенных критериев. Теперь, используя JPA, вам даже не нужно писать запросы, просто создайте интерфейс и методы с определенной номенклатурой Spring-JPA. Чтобы предоставить такие API, вы создадите уровень сервиса, который просто будет вызывать эти методы репозитория и, наконец, контроллеры, которые будут открывать конечные точки, вызывая уровень сервиса.

То, что здесь сделал Spring, позволяет вам открывать эти конечные точки из таких интерфейсов (репозиториев), которые обычно являются вызовами GET для поискового объекта и в фоновом режиме генерируют необходимые файлы для создания конечных конечных точек. Поэтому, если вы используете @RepositoryRestResource, тогда нет необходимости создавать уровень службы / контроллера.

С другой стороны, @RestController - это контроллер, который специально работает с данными json, а остальные работают как контроллер. Короче @Controller + @ResponseBody = @RestController.

Надеюсь это поможет.

См. Мой рабочий пример и блог о том же:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with -hibernate-без-контроллер

ШАЙЛУ
источник
Я вижу, как люди заходят в мой блог, если это решение работает, пожалуйста, проголосуйте.
shaILU
10

@RepositoryRestController переопределить сгенерированные по умолчанию контроллеры Spring Data REST из открытого репозитория.

Чтобы воспользоваться преимуществами настроек Spring Data REST, конвертеров сообщений, обработки исключений и многого другого, используйте @RepositoryRestControllerаннотацию вместо стандартного Spring MVC @Controllerили@RestController

Например, эти контроллеры используют spring.data.rest.basePathнастройку Spring Boot в качестве базового пути для маршрутизации.

См. Раздел Переопределение обработчиков ответов REST Spring Data .

Помните о добавлении, @ResponseBodyпоскольку оно отсутствует в@RepositoryRestController

Если вы не открыли репозиторий (помечен как @RepositoryRestResource(exported = false)), используйте @BasePathAwareControllerаннотацию

Также помните о сумках

ControllerLinkBuilder не принимает во внимание базовый путь Spring Data REST и @RequestMapping не должен использоваться на уровне класса / типа

а также

Базовый путь не отображается в HAL

Обходной путь для исправления ссылки: https://stackoverflow.com/a/51736503/548473

ОБНОВЛЕНИЕ: наконец, я предпочитаю не использовать @RepositoryRestControllerиз-за множества обходных путей.

Григорий Кислин
источник