Wann wird @RestController vs @RepositoryRestResource verwendet?

86

Ich habe mir verschiedene Beispiele für die Verwendung von Spring mit REST angesehen . Unser Endziel ist ein Spring- HATEOAS/HALSetup

Ich habe zwei verschiedene Methoden zum Rendern von REST im Frühjahr gesehen

  1. Über @RestControllereinen Controller

  2. Über @RepositoryRestResourceein Repository

Das, was ich nur schwer finden kann, ist, warum Sie eines über das andere verwenden sollten. Wenn Sie versuchen zu implementieren, HALwelches ist das Beste?

Unser Datenbank-Backend ist Neo4j .

Code
quelle

Antworten:

61

Ok, die Kurzgeschichte ist, dass Sie das verwenden möchten, @RepositoryRestResourceda dies einen HATEOAS- Service mit Spring JPA erstellt .

Wie Sie hier sehen können, haben Sie durch Hinzufügen dieser Anmerkung und Verknüpfen mit Ihrem Pojo einen voll funktionsfähigen HATEOAS- Dienst, ohne die Repository-Methode oder die REST- Dienstmethoden implementieren zu müssen

Wenn Sie das hinzufügen @RestController, müssen Sie jede Methode, die Sie verfügbar machen möchten, selbst implementieren. Außerdem wird diese Methode nicht in ein HATEOAS- Format exportiert .

zpontikas
quelle
7
Standardmäßig exportiert Spring Data REST ALLE öffentlichen Schnittstellen-Repositorys der obersten Ebene. Sie benötigen @RepositoryRestResource nur, um entweder KEINE Schnittstelle zu exportieren oder die Details des Endpunkts zu ändern.
Gregturn
4
Wenn Sie RestController mit Spring Data REST verwenden, umgehen Sie ALLES, was Spring Data REST bietet. Informationen zum Codieren eines benutzerdefinierten Spring MVC-Controllers, der die Nachrichtenkonverter von Spring Data REST usw. verwendet, finden Sie in BasePathAwareController.
Gregturn
Ich denke nicht, dass die akzeptierte Antwort richtig ist. @Gregturn hat die bessere Antwort.
Mark
38

Es gibt eine dritte (und vierte) Option, die Sie nicht beschrieben haben: Sie können entweder @BasePathAwareController oder @RepositoryRestController verwenden, je nachdem, ob Sie entitätsspezifische Aktionen ausführen oder nicht.

@RepositoryRestResource wird zum Festlegen von Optionen auf der öffentlichen Repository-Schnittstelle verwendet. Je nach Typ des zu erweiternden Repositorys (z. B. CrudRepository / PagingAndSortingRepository / usw.) werden automatisch Endpunkte erstellt.

@BasePathAwareController und @RepositoryRestController werden verwendet, wenn Sie Endpunkte manuell erstellen möchten, aber die von Ihnen eingerichteten Spring Data REST-Konfigurationen verwenden möchten.

Wenn Sie @RestController verwenden, erstellen Sie einen parallelen Satz von Endpunkten mit unterschiedlichen Konfigurationsoptionen - dh einem anderen Nachrichtenkonverter, verschiedenen Fehlerbehandlungsroutinen usw. -, die jedoch problemlos nebeneinander existieren (und wahrscheinlich Verwirrung stiften ).

Spezifische Dokumentation finden Sie hier .

Jacob Creed
quelle
6
Ich denke das ist nicht mehr wahr. Wenn a @RestControllerdenselben Pfad wie a verwendet @RepositoryRestResource, werden die Repository-Endpunkte nicht erstellt.
Hubert Grzeskowiak
19

Nun, die obigen Antworten sind in ihrem Kontext richtig, dennoch gebe ich Ihnen ein praktisches Beispiel.

In vielen Szenarien müssen wir als Teil der API Endpunkte für die Suche nach einer Entität anhand bestimmter Kriterien bereitstellen. Mit JPA müssen Sie jetzt nicht einmal mehr Abfragen schreiben, sondern nur eine Schnittstelle und Methoden mit einer bestimmten Nomenklatur von Spring-JPA erstellen. Um solche APIs verfügbar zu machen, erstellen Sie eine Service-Schicht, die diese Repository-Methoden einfach aufruft, und schließlich Controller, die Endpunkte durch Aufrufen der Service-Schicht verfügbar machen.

Was Spring hier getan hat, ermöglicht es Ihnen, diese Endpunkte über solche Schnittstellen (Repositorys) verfügbar zu machen, bei denen es sich im Allgemeinen um GET-Aufrufe für Suchentitäten handelt, und im Hintergrund die erforderlichen Dateien zum Erstellen der endgültigen Endpunkte zu generieren. Wenn Sie also @RepositoryRestResource verwenden, müssen Sie keine Service / Controller-Schicht erstellen.

Auf der anderen Seite ist @RestController ein Controller, der sich speziell mit JSON-Daten und Restarbeit als Controller befasst. Kurz gesagt @Controller + @ResponseBody = @RestController.

Hoffe das hilft.

Siehe mein Arbeitsbeispiel und mein Blog dazu:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with -Hibernate-No-Controller

shaILU
quelle
Ich kann Leute sehen, die zu meinem Blog gehen. Wenn diese Lösung funktioniert, stimmen Sie bitte ab.
ShaILU
10

@RepositoryRestController Überschreiben Sie standardmäßig generierte Spring Data REST-Controller aus dem exponierten Repository.

Verwenden Sie die @RepositoryRestControllerAnnotation anstelle einer Standard-Spring-MVC @Controlleroder von Spring Data REST, um die Einstellungen, Nachrichtenkonverter, die Ausnahmebehandlung usw. zu nutzen@RestController

Beispielsweise verwenden diese Controller die spring.data.rest.basePathSpring Boot-Einstellung als Basispfad für das Routing.

Siehe Überschreiben von REST-Antworthandlern für Federdaten .

Achten Sie auf das Hinzufügen, @ResponseBodyda es in fehlt@RepositoryRestController

Wenn Sie kein Repository verfügbar gemacht haben (markiert als @RepositoryRestResource(exported = false)), verwenden Sie @BasePathAwareControllerstattdessen eine Anmerkung

Achten Sie auch auf Taschen

ControllerLinkBuilderberücksichtigt nicht den Basispfad von Spring Data REST und @RequestMappingsollte nicht auf Klassen- / Typebene verwendet werden

und

Der Basispfad wird in HAL nicht angezeigt

Problemumgehung zur Behebung des Links: https://stackoverflow.com/a/51736503/548473

UPDATE: Endlich bevorzuge ich es @RepositoryRestControllerwegen vieler Problemumgehungen nicht zu verwenden .

Grigory Kislin
quelle