ใน 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 ในโค้ดที่ซับซ้อนมากขึ้น