Khi nào sử dụng @RestController so với @RepositoryRestResource


87

Tôi đã xem nhiều ví dụ khác nhau về cách sử dụng Spring với REST . Mục tiêu cuối cùng của chúng tôi là HATEOAS/HALthiết lập Spring

Tôi đã thấy hai phương pháp khác nhau để hiển thị REST trong Spring

  1. Qua @RestControllertrong Bộ điều khiển

  2. Qua @RepositoryRestResourcetrong Kho lưu trữ

Điều tôi đang đấu tranh để tìm là tại sao bạn lại sử dụng cái này thay cho cái kia. Khi cố gắng thực hiện HALcái nào là tốt nhất?

Cơ sở dữ liệu phụ trợ của chúng tôi là Neo4j .

Câu trả lời:


61

Ok, câu chuyện ngắn là bạn muốn sử dụng @RepositoryRestResourcevì điều này tạo ra dịch vụ HATEOAS với Spring JPA .

Như bạn có thể thấy ở đây, thêm chú thích này và liên kết nó với Pojo của bạn, bạn có một dịch vụ HATEOAS đầy đủ chức năng mà không cần phải triển khai phương thức kho lưu trữ hoặc phương thức dịch vụ REST

Nếu bạn thêm @RestControllerthì bạn phải thực hiện từng phương pháp mà bạn muốn tự hiển thị và nó cũng không xuất nó sang định dạng HATEOAS .


7
Theo mặc định, Spring Data REST sẽ xuất TẤT CẢ các kho lưu trữ giao diện công khai, cấp cao nhất. Bạn chỉ cần @RepositoryRestResource để KHÔNG xuất giao diện hoặc để thay đổi chi tiết của điểm cuối.
gregturn

4
Nếu bạn sử dụng RestController với Spring Data REST, bạn sẽ bỏ qua MỌI THỨ mà Spring Data REST cung cấp. Để viết mã bộ điều khiển Spring MVC tùy chỉnh sử dụng bộ chuyển đổi thông báo của REST dữ liệu Spring, v.v., hãy xem BasePathAwareController.
gregturn

Tôi không nghĩ câu trả lời được chấp nhận là đúng @gregturn có câu trả lời tốt hơn.
Đánh dấu

39

Có một tùy chọn thứ ba (và thứ tư) mà bạn chưa vạch ra, đó là sử dụng @BasePathAwareController hoặc @RepositoryRestController, tùy thuộc vào việc bạn có đang thực hiện các hành động dành riêng cho thực thể hay không.

@RepositoryRestResource được sử dụng để đặt các tùy chọn trên giao diện Kho lưu trữ công cộng - nó sẽ tự động tạo các điểm cuối khi thích hợp dựa trên loại Kho lưu trữ đang được mở rộng (tức là CrudRepository / PagingAndSortingRepository / v.v.).

@BasePathAwareController và @RepositoryRestController được sử dụng khi bạn muốn tạo các điểm cuối theo cách thủ công, nhưng muốn sử dụng cấu hình Spring Data REST mà bạn đã thiết lập.

Nếu bạn sử dụng @RestController, bạn sẽ tạo một tập hợp các điểm cuối song song với các tùy chọn cấu hình khác nhau - tức là một trình chuyển đổi thông báo khác nhau, trình xử lý lỗi khác nhau, v.v. - nhưng chúng sẽ vui vẻ cùng tồn tại (và có thể gây nhầm lẫn).

Tài liệu cụ thể có thể được tìm thấy tại đây .


6
Tôi nghĩ điều này không còn đúng nữa. Nếu a @RestControllersử dụng cùng một đường dẫn với a @RepositoryRestResource, các điểm cuối của kho lưu trữ sẽ không được tạo.
Hubert Grzeskowiak

19

Vâng, các câu trả lời trên là chính xác trong ngữ cảnh của chúng, tôi vẫn đưa ra ví dụ thực tế cho bạn.

Trong nhiều trường hợp với tư cách là một phần của API, chúng tôi cần cung cấp các điểm cuối để tìm kiếm một thực thể dựa trên các tiêu chí nhất định. Bây giờ sử dụng JPA, bạn thậm chí không cần phải viết các truy vấn, chỉ cần tạo một giao diện và các phương thức với danh pháp cụ thể của Spring-JPA. Để hiển thị các API như vậy, bạn sẽ tạo lớp Dịch vụ mà đơn giản là gọi các phương thức kho lưu trữ này và cuối cùng là Bộ điều khiển sẽ hiển thị các điểm cuối bằng cách gọi lớp Dịch vụ.

Những gì Spring đã làm ở đây, cho phép bạn hiển thị các điểm cuối này từ các giao diện như vậy (kho lưu trữ) thường là các lệnh gọi GET tới thực thể tìm kiếm và trong nền tạo ra các tệp cần thiết để tạo điểm cuối cuối cùng. Vì vậy, nếu bạn đang sử dụng @RepositoryRestResource thì không cần tạo lớp Service / Controller.

Mặt khác, @RestController là bộ điều khiển đặc biệt xử lý dữ liệu json và phần còn lại hoạt động như một bộ điều khiển. Nói ngắn gọn là @Controller + @ResponseBody = @RestController.

Hi vọng điêu nay co ich.

Xem ví dụ làm việc của tôi và blog giống nhau:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with -hibernate-no-controller


Tôi có thể thấy mọi người vào blog của tôi, nếu giải pháp này hoạt động, vui lòng bỏ phiếu.
shaILU

10

@RepositoryRestController ghi đè bộ điều khiển Spring Data REST được tạo mặc định từ kho lưu trữ được tiếp xúc.

Để tận dụng các cài đặt của Spring Data REST, trình chuyển đổi thông báo, xử lý ngoại lệ, v.v., hãy sử dụng @RepositoryRestControllerchú thích thay vì Spring MVC tiêu chuẩn @Controllerhoặc@RestController

Ví dụ: bộ điều khiển này sử dụng spring.data.rest.basePathcài đặt Spring Boot làm đường dẫn cơ sở để định tuyến.

Xem Ghi đè trình xử lý phản hồi REST dữ liệu mùa xuân .

Hãy lưu ý bổ sung @ResponseBodyvì nó bị thiếu trong@RepositoryRestController

Nếu bạn không tiếp xúc với kho lưu trữ (được đánh dấu là @RepositoryRestResource(exported = false)), hãy sử dụng @BasePathAwareControllerchú thích để thay thế

Cũng cần lưu ý về túi

ControllerLinkBuilderkhông tính đến đường dẫn cơ sở của Spring Data REST và @RequestMappingkhông được sử dụng ở cấp độ lớp / loại

Đường dẫn cơ sở không hiển thị trong HAL

Giải pháp khắc phục liên kết: https://stackoverflow.com/a/51736503/548473

CẬP NHẬT: cuối cùng tôi không muốn sử dụng @RepositoryRestControllerdo có nhiều cách giải quyết.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.