เมื่อใดควรใช้ @RestController vs @RepositoryRestResource


87

ฉันได้รับการดูตัวอย่างต่างๆของวิธีการใช้ฤดูใบไม้ผลิที่มีส่วนที่เหลือ เป้าหมายสุดท้ายของเราคือการHATEOAS/HALตั้งค่าSpring

ฉันได้เห็นสองวิธีที่แตกต่างกันในการเรนเดอร์RESTภายในSpring

  1. ผ่าน@RestControllerภายในคอนโทรลเลอร์

  2. ผ่าน@RepositoryRestResourceภายใน Repository

สิ่งที่ฉันกำลังดิ้นรนเพื่อค้นหาคือทำไมคุณถึงใช้อีกอันหนึ่ง เมื่อพยายามที่จะใช้HALสิ่งที่ดีที่สุด?

แบ็กเอนด์ฐานข้อมูลของเราคือNeo4j

คำตอบ:


62

ตกลงดังนั้นเรื่องราวสั้น ๆ ว่าคุณต้องการที่จะใช้@RepositoryRestResourceตั้งแต่นี้สร้างHATEOASบริการกับฤดูใบไม้ผลิ JPA

ดังที่คุณเห็นที่นี่การเพิ่มคำอธิบายประกอบนี้และเชื่อมโยงกับ Pojo ของคุณคุณมีบริการHATEOAS ที่ทำงานได้อย่างสมบูรณ์โดยไม่ต้องใช้เมธอดที่เก็บหรือวิธีการบริการ REST

หากคุณเพิ่มเข้าไป@RestControllerคุณจะต้องใช้แต่ละวิธีที่คุณต้องการเปิดเผยด้วยตัวคุณเองและจะไม่ส่งออกเป็นรูปแบบHATEOAS


7
ตามค่าเริ่มต้น Spring Data REST จะส่งออกที่เก็บอินเทอร์เฟซสาธารณะระดับบนสุดทั้งหมด คุณต้องการเพียง @RepositoryRestResource เพื่อไม่ส่งออกอินเทอร์เฟซหรือเพื่อแก้ไขรายละเอียดของจุดสิ้นสุด
gregturn

4
หากคุณใช้ RestController กับ Spring Data REST คุณจะหลีกเลี่ยงทุกสิ่งที่ Spring Data REST ให้ หากต้องการโค้ดตัวควบคุม Spring MVC แบบกำหนดเองที่ใช้ตัวแปลงข้อความของ Spring data REST เป็นต้นให้ดูที่ BasePathAwareController
gregturn

ฉันไม่คิดว่าคำตอบที่ยอมรับนั้นถูกต้อง @gregturn มีคำตอบที่ดีกว่า
มาร์ค

39

มีตัวเลือกที่สาม (และสี่) ที่คุณไม่ได้ระบุไว้ซึ่งก็คือการใช้ @BasePathAwareController หรือ @RepositoryRestController ขึ้นอยู่กับว่าคุณกำลังดำเนินการเฉพาะเอนทิตีหรือไม่

@RepositoryRestResource ใช้เพื่อตั้งค่าอ็อพชันบนอินเทอร์เฟซ Repository สาธารณะ - จะสร้างจุดสิ้นสุดโดยอัตโนมัติตามความเหมาะสมตามประเภทของ Repository ที่กำลังขยาย (เช่น CrudRepository / PagingAndSortingRepository / etc)

@BasePathAwareController และ @RepositoryRestController ใช้เมื่อคุณต้องการสร้างจุดสิ้นสุดด้วยตนเอง แต่ต้องการใช้การกำหนดค่า Spring Data REST ที่คุณตั้งค่าไว้

ถ้าคุณใช้ @RestController คุณจะสร้างชุดขนานของปลายทางที่มีแตกต่างกันตั้งค่าตัวเลือก - คือแปลงข้อความที่แตกต่างกันจัดการข้อผิดพลาดที่แตกต่างกัน ฯลฯ - แต่พวกเขามีความสุขที่จะอยู่ร่วมกัน (และอาจจะทำให้เกิดความสับสน)

เอกสารที่เฉพาะเจาะจงสามารถพบได้ที่นี่


6
ฉันคิดว่านี่ไม่เป็นความจริงอีกต่อไป หาก@RestControllerใช้เส้นทางเดียวกันกับ a @RepositoryRestResourceจะไม่มีการสร้างจุดสิ้นสุดที่เก็บ
Hubert Grzeskowiak

19

คำตอบข้างต้นนั้นถูกต้องในบริบทของพวกเขา แต่ฉันยังให้ตัวอย่างที่ใช้ได้จริง

ในหลาย ๆ สถานการณ์ที่เป็นส่วนหนึ่งของ API เราจำเป็นต้องจัดเตรียมจุดสิ้นสุดสำหรับการค้นหาเอนทิตีตามเกณฑ์ที่กำหนด ตอนนี้ใช้ JPA คุณไม่จำเป็นต้องเขียนแบบสอบถามเพียงแค่สร้างอินเทอร์เฟซและวิธีการด้วยระบบการตั้งชื่อเฉพาะของ Spring-JPA ในการเปิดเผย API ดังกล่าวคุณจะสร้างเลเยอร์บริการซึ่งจะเรียกวิธีการเก็บข้อมูลเหล่านี้และในที่สุดตัวควบคุมซึ่งจะเปิดเผยจุดสิ้นสุดโดยเรียกใช้เลเยอร์บริการ

สิ่งที่ Spring ทำที่นี่ช่วยให้คุณสามารถเปิดเผยจุดสิ้นสุดเหล่านี้จากอินเทอร์เฟซดังกล่าว (ที่เก็บ) ซึ่งโดยทั่วไป GET เรียกไปยังเอนทิตีการค้นหาและในพื้นหลังจะสร้างไฟล์ที่จำเป็นเพื่อสร้างปลายทางสุดท้าย ดังนั้นหากคุณใช้ @RepositoryRestResource ก็ไม่จำเป็นต้องสร้างเลเยอร์ Service / Controller

ในทางกลับกัน @RestController เป็นคอนโทรลเลอร์ที่เกี่ยวข้องกับข้อมูล json โดยเฉพาะและส่วนที่เหลือจะทำงานเป็นคอนโทรลเลอร์ ในระยะสั้น @Controller + @ResponseBody = @RestController

หวังว่านี่จะช่วยได้

ดูตัวอย่างการทำงานของฉันและบล็อกเดียวกัน:
http://sv-technical.blogspot.com/2015/11/spring-boot-and-repositoryrestresource.html
https://github.com/svermaji/Spring-boot-with - ไฮเบอร์เนตไม่มีตัวควบคุม


ฉันเห็นคนไปที่บล็อกของฉันหากวิธีนี้ใช้ได้ผลโปรดโหวต
shaILU

10

@RepositoryRestController แทนที่ตัวควบคุม Spring Data REST ที่สร้างโดยดีฟอลต์จากที่เก็บข้อมูลที่เปิดเผย

หากต้องการใช้ประโยชน์จากการตั้งค่า Spring Data REST ตัวแปลงข้อความการจัดการข้อยกเว้นและอื่น ๆ ให้ใช้@RepositoryRestControllerคำอธิบายประกอบแทน Spring MVC มาตรฐาน@Controllerหรือ@RestController

เช่นคอนโทรลเลอร์นี้ใช้spring.data.rest.basePathการตั้งค่า Spring Boot เป็นเส้นทางฐานสำหรับการกำหนดเส้นทาง

ดูเอาชนะฤดูใบไม้ผลิข้อมูล REST ตอบสนอง Handlers

ระวังการเพิ่ม@ResponseBodyเนื่องจากพลาด@RepositoryRestController

หากคุณไม่เปิดเผยที่เก็บ (ทำเครื่องหมายเป็น@RepositoryRestResource(exported = false)) ให้ใช้@BasePathAwareControllerคำอธิบายประกอบแทน

ระวังกระเป๋าด้วย

ControllerLinkBuilderไม่ได้คำนึงถึงเส้นทางพื้นฐานของ Spring Data REST และ@RequestMappingไม่ควรใช้ในระดับคลาส / ประเภท

และ

เส้นทางฐานไม่แสดงใน HAL

วิธีแก้ปัญหาเพื่อแก้ไขลิงก์: https://stackoverflow.com/a/51736503/548473

UPDATE: ในที่สุดฉันไม่ต้องการใช้@RepositoryRestControllerเนื่องจากมีวิธีแก้ปัญหามากมาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.