ใน Spring WebFlux นักพัฒนาสามารถเลือกใช้งานได้ทั้งแบบ @RestController และ Router Function เพื่อสร้าง REST API ซึ่งทั้งสองแนวทางต่างมีข้อดีและข้อจำกัดที่แตกต่างกัน บทความนี้จะพาคุณไปเข้าใจการใช้งานทั้งสองวิธี พร้อมตัวอย่างโค้ดและภาพอธิบายอย่างชัดเจน

1. การใช้งาน @RestController
เป็นแนวทางที่หลายคนคุ้นเคยจาก Spring MVC โดยใช้ annotation ในการแม็พ endpoint และเขียน logic ใน class controller ได้โดยตรง
ตัวอย่าง:
@RestController @RequestMapping("/api") public class HelloController { @GetMapping("/hello") public Mono<String> sayHello() { return Mono.just("Hello from @RestController"); } }
ข้อดี
- อ่านง่าย เข้าใจง่าย เหมาะกับผู้ที่คุ้นเคย Spring MVC
- เขียนแบบ declarative ได้
- มีการใช้งานอย่างแพร่หลาย
ข้อเสีย
- ไม่เหมาะกับ functional style
- การจัดการกับ route หลายกรณีซับซ้อนขึ้น
2. การใช้งาน Router Function
Router Function เป็นแนวทางแบบ functional programming ในการแม็พ route ไปยัง handler function มีความยืดหยุ่นและเหมาะสำหรับระบบขนาดเล็กหรือ route ที่ซับซ้อน
ตัวอย่าง:
// Router @Configuration public class RouterConfig { @Bean public RouterFunction<ServerResponse> route(HelloHandler handler) { return RouterFunctions .route(GET("/api/hello"), handler::sayHello); } } // Handler @Component public class HelloHandler { public Mono<ServerResponse> sayHello(ServerRequest request) { return ServerResponse.ok().bodyValue("Hello from RouterFunction"); } }
ข้อดี
- แยกความรับผิดชอบชัดเจน (routing vs logic)
- ยืดหยุ่น เหมาะกับ DSL style
- ดีต่อ testing และ mock handler
ข้อเสีย
- อ่านยากกว่าสำหรับผู้เริ่มต้น
- debug routing ยากกว่า annotation
ภาพประกอบ: การเปรียบเทียบ @RestController vs Router Function

การจัดการกับ Path Variables และ Query Params
แบบ @RestController
@GetMapping("/hello/{name}") public Mono<String> greet(@PathVariable String name) { return Mono.just("Hello " + name); }
แบบ Router Function
@GetMapping("/hello/{name}") public Mono<ServerResponse> greet(ServerRequest request) { String name = request.pathVariable("name"); return ServerResponse.ok().bodyValue("Hello " + name); }
เมื่อไรควรใช้แบบใด?
เลือกใช้ @RestController เมื่อ:
- ทำระบบ CRUD หรือ REST API ธรรมดา
- ทีมงานคุ้นเคย Spring MVC
- ต้องการเขียนแบบ annotation-based
เลือกใช้ Router Function เมื่อ:
- ต้องการ functional style ที่ชัดเจน
- ระบบมี dynamic route หรือต้อง mapping หลายชั้น
- ต้องการ separation of concerns สูง
แหล่งเรียนรู้เพิ่มเติม
สรุป
ทั้ง @RestController และ Router Function มีจุดเด่นในแบบของตัวเอง และสามารถอยู่ร่วมกันได้ในระบบเดียวกัน การเลือกใช้งานควรดูจากความถนัดของทีม ขนาดของระบบ และรูปแบบการใช้งาน หากคุณเริ่มต้นกับ WebFlux วิธีที่ง่ายที่สุดคือเริ่มจาก @RestController แล้วค่อย ๆ สำรวจ Router Function ในโค้ดที่ซับซ้อนมากขึ้น