Kapan menggunakan @RestController vs @RepositoryRestResource

87

Saya telah melihat berbagai contoh cara menggunakan Spring dengan REST . Target akhir kami adalah HATEOAS/HALpengaturan Musim Semi

Saya telah melihat dua metode berbeda untuk merender REST dalam Spring

  1. Melalui @RestControllerdalam Kontroler

  2. Melalui @RepositoryRestResourcedalam Repositori

Hal yang saya perjuangkan untuk menemukan adalah mengapa Anda menggunakan salah satu dari yang lain. Saat mencoba menerapkan HALmana yang terbaik?

Backend database kami adalah Neo4j .

kode
sumber

Jawaban:

62

Oke, jadi cerita singkatnya adalah Anda ingin menggunakan @RepositoryRestResourcekarena ini membuat layanan HATEOAS dengan Spring JPA .

Seperti yang Anda lihat di sini menambahkan anotasi ini dan menautkannya ke Pojo Anda, Anda memiliki layanan HATEOAS yang berfungsi penuh tanpa harus menerapkan metode repositori atau metode layanan REST

Jika Anda menambahkan @RestControllermaka Anda harus menerapkan setiap metode yang ingin Anda ekspos sendiri dan juga tidak mengekspor ini ke format HATEOAS .

zpontikas
sumber
7
Secara default, Spring Data REST akan mengekspor SEMUA repositori antarmuka publik tingkat atas. Anda hanya perlu @RepositoryRestResource untuk TIDAK mengekspor antarmuka, atau mengubah detail titik akhir.
gregturn
4
Jika Anda menggunakan RestController dengan Spring Data REST, Anda akan menghindari SEMUA yang disediakan Spring Data REST. Untuk membuat kode pengontrol MVC Spring khusus yang menggunakan konverter pesan REST data Spring, dll., Lihat BasePathAwareController.
gregturn
Saya tidak berpikir jawaban yang diterima benar @gregturn memiliki jawaban yang lebih baik.
Tandai
39

Ada opsi ketiga (dan keempat) yang belum Anda buat garis besarnya, yaitu menggunakan @BasePathAwareController atau @RepositoryRestController, bergantung pada apakah Anda melakukan tindakan khusus entitas atau tidak.

@RepositoryRestResource digunakan untuk menyetel opsi pada antarmuka Repositori publik - ini akan secara otomatis membuat titik akhir yang sesuai berdasarkan jenis Repositori yang sedang diperluas (yaitu CrudRepository / PagingAndSortingRepository / dll).

@BasePathAwareController dan @RepositoryRestController digunakan saat Anda ingin membuat endpoint secara manual, tetapi ingin menggunakan konfigurasi Spring Data REST yang telah Anda siapkan.

Jika Anda menggunakan @RestController, Anda akan membuat serangkaian titik akhir paralel dengan opsi konfigurasi yang berbeda - yaitu konverter pesan yang berbeda, penangan kesalahan yang berbeda, dll - tetapi mereka akan dengan senang hati hidup berdampingan (dan mungkin menyebabkan kebingungan).

Dokumentasi khusus dapat ditemukan di sini .

Jacob Creed
sumber
6
Saya pikir ini tidak lagi benar. Jika a @RestControllermenggunakan jalur yang sama dengan a @RepositoryRestResource, titik akhir repositori tidak akan dibuat.
Hubert Grzeskowiak
19

Nah, jawaban di atas benar dalam konteksnya masih saya beri contoh praktis.

Dalam banyak skenario sebagai bagian dari API kita perlu menyediakan titik akhir untuk mencari entitas berdasarkan kriteria tertentu. Sekarang menggunakan JPA Anda bahkan tidak perlu menulis kueri, cukup buat antarmuka dan metode dengan nomenklatur khusus Spring-JPA. Untuk mengekspos API seperti itu, Anda akan membuat lapisan Layanan yang hanya akan memanggil metode repositori ini dan terakhir Pengontrol yang akan mengekspos titik akhir dengan memanggil lapisan Layanan.

Apa yang dilakukan Spring di sini, memungkinkan Anda untuk mengekspos titik akhir ini dari antarmuka (repositori) yang umumnya merupakan panggilan GET ke entitas pencarian dan di latar belakang menghasilkan file yang diperlukan untuk membuat titik akhir akhir. Jadi jika Anda menggunakan @RepositoryRestResource maka tidak perlu membuat lapisan Service / Controller.

Di sisi lain @RestController adalah pengontrol yang secara khusus menangani data json dan sisanya berfungsi sebagai pengontrol. Singkatnya @Controller + @ResponseBody = @RestController.

Semoga ini membantu.

Lihat contoh kerja saya dan blog untuk hal yang sama:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with -hibernate-no-controller

shaILU
sumber
Saya dapat melihat orang-orang mengunjungi blog saya, jika solusi ini berhasil, silakan pilih.
shaILU
10

@RepositoryRestController mengganti pengontrol REST Data Musim Semi yang dibuat secara default dari repositori yang terekspos.

Untuk memanfaatkan pengaturan Spring Data REST, konverter pesan, penanganan pengecualian, dan banyak lagi, gunakan @RepositoryRestControlleranotasi sebagai ganti Spring MVC standar @Controlleratau@RestController

Misalnya pengontrol ini menggunakan spring.data.rest.basePathpengaturan Spring Boot sebagai jalur dasar untuk perutean.

Lihat Mengganti Penangan Respons REST Data Musim Semi .

Berhati-hatilah untuk menambahkan @ResponseBodykarena terlewat@RepositoryRestController

Jika Anda tidak mengekspos repositori (ditandai sebagai @RepositoryRestResource(exported = false)), gunakan @BasePathAwareControlleranotasi sebagai gantinya

Waspadai juga tas

ControllerLinkBuildertidak memperhitungkan jalur dasar REST Spring Data dan @RequestMappingtidak boleh digunakan pada tingkat kelas / tipe

dan

Jalur dasar tidak muncul di HAL

Solusi untuk memperbaiki tautan: https://stackoverflow.com/a/51736503/548473

PEMBARUAN: akhirnya saya memilih untuk tidak menggunakan @RepositoryRestControllerkarena banyak solusi.

Grigory Kislin
sumber