Quando usar @RestController vs @RepositoryRestResource

87

Tenho visto vários exemplos de como usar o Spring com REST . Nosso objetivo final é uma HATEOAS/HALconfiguração de Spring

Eu vi dois métodos distintos para renderizar REST no Spring

  1. Por meio de @RestControllerum controlador

  2. Por meio de @RepositoryRestResourceum Repositório

O que estou lutando para descobrir é por que você usaria um em vez do outro. Ao tentar implementar o HALque é melhor?

Nosso backend de banco de dados é Neo4j .

código
fonte

Respostas:

61

Ok, resumindo, você deseja usar o, @RepositoryRestResourcepois isso cria um serviço HATEOAS com Spring JPA .

Como você pode ver aqui, adicionando esta anotação e ligando-a ao seu Pojo, você tem um serviço HATEOAS totalmente funcional sem ter que implementar o método de repositório ou os métodos de serviço REST

Se você adicionar o @RestController, terá que implementar cada método que deseja expor por conta própria e também não exportar para um formato HATEOAS .

zpontikas
fonte
7
Por padrão, Spring Data REST exportará TODOS os repositórios de interface pública de nível superior. Você só precisa de @RepositoryRestResource para NÃO exportar uma interface ou para alterar os detalhes do terminal.
gregturn
4
Se você usar RestController com Spring Data REST, você evitará TUDO que o Spring Data REST fornece. Para codificar um controlador Spring MVC customizado que usa conversores de mensagem REST de dados Spring, etc., examine BasePathAwareController.
gregturn
Não acho que a resposta aceita seja a correta @gregturn tem a melhor resposta.
Marcos
39

Há uma terceira (e quarta) opção que você não descreveu, que é usar @BasePathAwareController ou @RepositoryRestController, dependendo se você está executando ações específicas da entidade ou não.

@RepositoryRestResource é usado para definir opções na interface pública do Repositório - ele criará pontos de extremidade automaticamente conforme apropriado com base no tipo de Repositório que está sendo estendido (ou seja, CrudRepository / PagingAndSortingRepository / etc).

@BasePathAwareController e @RepositoryRestController são usados ​​quando você deseja criar pontos de extremidade manualmente, mas deseja usar as configurações REST do Spring Data que você definiu.

Se você usar @RestController, você criará um conjunto paralelo de endpoints com diferentes opções de configuração - isto é, um conversor de mensagem diferente, diferentes manipuladores de erro, etc. - mas eles coexistirão alegremente (e provavelmente causarão confusão).

A documentação específica pode ser encontrada aqui .

Jacob Creed
fonte
6
Acho que isso não é mais verdade. Se a @RestControllerusar o mesmo caminho que a @RepositoryRestResource, os pontos de extremidade do repositório não serão criados.
Hubert Grzeskowiak
19

Bem, as respostas acima estão corretas em seu contexto, mas estou dando um exemplo prático.

Em muitos cenários, como parte da API, precisamos fornecer pontos de extremidade para pesquisar uma entidade com base em determinados critérios. Agora usando JPA você não precisa nem mesmo escrever queries, basta fazer uma interface e métodos com nomenclatura específica de Spring-JPA. Para expor essas APIs, você criará a camada de serviço, que simplesmente chamaria esses métodos de repositório e, finalmente, os controladores que exporão os pontos de extremidade chamando a camada de serviço.

O que o Spring fez aqui, permite que você exponha esses endpoints de tais interfaces (repositórios) que geralmente são chamadas GET para pesquisar entidade e em segundo plano gera os arquivos necessários para criar endpoints finais. Portanto, se você estiver usando @RepositoryRestResource, não há necessidade de criar a camada de Serviço / Controlador.

Por outro lado, @RestController é um controlador que lida especificamente com dados json e o resto do trabalho como controlador. Resumindo @Controller + @ResponseBody = @RestController.

Espero que isto ajude.

Veja meu exemplo de trabalho e blog para o mesmo:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with -hibernate-no-controller

shaILU
fonte
Eu posso ver pessoas indo para o meu blog, se esta solução funcionar, vote.
shaILU
10

@RepositoryRestController sobrescrever controladores Spring Data REST padrão gerados a partir do repositório exposto.

Para tirar proveito das configurações do Spring Data REST, conversores de mensagem, tratamento de exceção e muito mais, use a @RepositoryRestControlleranotação em vez de um Spring MVC padrão @Controllerou@RestController

Por exemplo, esses controladores usam a spring.data.rest.basePathconfiguração Spring Boot como caminho base para o roteamento.

Consulte Substituindo Manipuladores de Resposta REST do Spring Data .

Esteja ciente de adicionar @ResponseBody, pois está faltando@RepositoryRestController

Se você não expôs o repositório (marcado como @RepositoryRestResource(exported = false)), use a @BasePathAwareControlleranotação em seu lugar

Também esteja ciente de bolsas

ControllerLinkBuildernão leva o caminho base do Spring Data REST em consideração e @RequestMappingnão deve ser usado em nível de classe / tipo

e

O caminho de base não aparece no HAL

Solução alternativa para corrigir o link: https://stackoverflow.com/a/51736503/548473

ATUALIZAÇÃO: finalmente prefiro não usar @RepositoryRestControllerdevido a muitas soluções alternativas.

Grigory Kislin
fonte