Quand utiliser @RestController vs @RepositoryRestResource

87

J'ai examiné divers exemples d'utilisation de Spring avec REST . Notre objectif final est une HATEOAS/HALconfiguration Spring

J'ai vu deux méthodes distinctes pour rendre REST dans Spring

  1. Via @RestControllerau sein d'un contrôleur

  2. Via @RepositoryRestResourcedans un référentiel

Ce que j'ai du mal à trouver, c'est pourquoi vous utiliseriez l'un sur l'autre. Lorsque vous essayez de mettre en œuvre HALce qui est le mieux?

Notre backend de base de données est Neo4j .

code
la source

Réponses:

61

Ok, donc la petite histoire est que vous voulez utiliser le @RepositoryRestResourcecar cela crée un service HATEOAS avec Spring JPA .

Comme vous pouvez le voir ici en ajoutant cette annotation et en la liant à votre Pojo, vous disposez d'un service HATEOAS entièrement fonctionnel sans avoir à implémenter la méthode de référentiel ou les méthodes de service REST

Si vous ajoutez le, @RestControllervous devez implémenter chaque méthode que vous souhaitez exposer vous-même et il ne l'exporte pas non plus au format HATEOAS .

zpontikas
la source
7
Par défaut, Spring Data REST exportera TOUS les référentiels d'interface publique de niveau supérieur. Vous n'avez besoin que de @RepositoryRestResource pour NE PAS exporter une interface ou pour modifier les détails du point de terminaison.
gregturn
4
Si vous utilisez RestController avec Spring Data REST, vous éviterez TOUT ce que Spring Data REST fournit. Pour coder un contrôleur Spring MVC personnalisé qui utilise les convertisseurs de messages de Spring Data REST, etc., consultez BasePathAwareController.
gregturn
Je ne pense pas que la réponse acceptée soit correcte. @Gregturn a la meilleure réponse.
Mark
39

Il existe une troisième (et quatrième) option que vous n'avez pas décrite, qui consiste à utiliser @BasePathAwareController ou @RepositoryRestController, selon que vous exécutez ou non des actions spécifiques à l'entité.

@RepositoryRestResource est utilisé pour définir des options sur l'interface du référentiel public - il créera automatiquement des points de terminaison selon le cas en fonction du type de référentiel en cours d'extension (c'est-à-dire CrudRepository / PagingAndSortingRepository / etc).

@BasePathAwareController et @RepositoryRestController sont utilisés lorsque vous souhaitez créer manuellement des points de terminaison, mais que vous souhaitez utiliser les configurations Spring Data REST que vous avez configurées.

Si vous utilisez @RestController, vous allez créer un ensemble parallèle de points de terminaison avec différents options de configuration - c'est-à-dire un convertisseur de message différent, différents gestionnaires d'erreurs, etc. - mais ils coexisteront volontiers (et causeront probablement de la confusion).

Une documentation spécifique peut être trouvée ici .

Jacob Creed
la source
6
Je pense que ce n'est plus vrai. Si a @RestControllerutilise le même chemin que a @RepositoryRestResource, les points de terminaison du référentiel ne seront pas créés.
Hubert Grzeskowiak
19

Eh bien, les réponses ci-dessus sont correctes dans leur contexte, mais je vous donne un exemple pratique.

Dans de nombreux scénarios, dans le cadre de l'API, nous devons fournir des points de terminaison pour rechercher une entité en fonction de certains critères. Maintenant, en utilisant JPA, vous n'avez même pas besoin d'écrire des requêtes, il suffit de créer une interface et des méthodes avec la nomenclature spécifique de Spring-JPA. Pour exposer ces API, vous créerez une couche de service qui appellerait simplement ces méthodes de référentiel et enfin des contrôleurs qui exposeront les points de terminaison en appelant la couche de service.

Ce que Spring a fait ici, vous permet d'exposer ces points de terminaison à partir de telles interfaces (référentiels) qui sont généralement des appels GET pour rechercher une entité et en arrière-plan génère les fichiers nécessaires pour créer des points de terminaison finaux. Donc, si vous utilisez @RepositoryRestResource, il n'est pas nécessaire de créer une couche Service / Controller.

D'autre part, @RestController est un contrôleur qui traite spécifiquement les données json et le reste du travail en tant que contrôleur. En bref @Controller + @ResponseBody = @RestController.

J'espère que cela t'aides.

Voir mon exemple de travail et mon blog pour le même:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with -hibernate-no-controller

shaILU
la source
Je peux voir des gens accéder à mon blog, si cette solution fonctionne, veuillez voter.
shaILU
10

@RepositoryRestController remplacer les contrôleurs REST Spring Data générés par défaut à partir du référentiel exposé.

Pour tirer parti des paramètres de Spring Data REST, des convertisseurs de messages, de la gestion des exceptions, etc., utilisez l' @RepositoryRestControllerannotation au lieu d'un Spring MVC standard @Controllerou@RestController

Par exemple, ces contrôleurs utilisent le spring.data.rest.basePathparamètre Spring Boot comme chemin de base pour le routage.

Consultez Remplacement des gestionnaires de réponse REST Spring Data .

Soyez conscient de l'ajout @ResponseBodycar il est manqué dans@RepositoryRestController

Si vous n'avez pas exposé le référentiel (marqué comme @RepositoryRestResource(exported = false)), utilisez @BasePathAwareControllerplutôt l'annotation

Faites également attention aux sacs

ControllerLinkBuilderne prend pas en compte le chemin de base de Spring Data REST et @RequestMappingne doit pas être utilisé au niveau de la classe / type

et

Le chemin de base n'apparaît pas dans HAL

Solution de contournement pour corriger le lien: https://stackoverflow.com/a/51736503/548473

MISE À JOUR: enfin, je préfère ne pas utiliser en @RepositoryRestControllerraison de nombreuses solutions de contournement.

Grigory Kislin
la source