Spring WebFlux คืออะไร?
Spring WebFlux เป็น framework สำหรับการพัฒนา web application ที่ใช้แนวคิด Reactive Programming ซึ่งออกแบบมาสำหรับระบบที่ต้องการ high throughput, low latency และรองรับการประมวลผล asynchronous แบบ non-blocking โดยใช้ Project Reactor (Mono/Flux) เป็นแกนหลัก
แตกต่างจาก Spring MVC ที่ใช้ servlet blocking I/O, WebFlux รองรับทั้ง Netty และ servlet container (เช่น Tomcat) แต่จะทำงานแบบ non-blocking ซึ่งเหมาะสำหรับ workload ที่เน้น concurrent สูง เช่น streaming, chat, IoT, และ API ที่มี response time สั้น
ข้อดีของ Spring WebFlux
- รองรับ high concurrency ด้วย memory footprint ที่ต่ำ
- ประมวลผลแบบ asynchronous non-blocking โดยใช้ Mono และ Flux
- รองรับ Server-Sent Events (SSE), WebSocket ได้ดี
- สามารถใช้กับ Netty, Undertow หรือ Tomcat ได้
- สามารถ scale ได้ดีในระบบ cloud หรือ microservice
ข้อเสียของ Spring WebFlux
- เรียนรู้ยากกว่า Spring MVC
- Debugging stack trace ซับซ้อน
- ต้องออกแบบระบบให้เข้าใจ reactive flow (backpressure, flatMap, etc.)
- บาง library/classic library ไม่รองรับ reactive (ต้องใช้ adapter)
เริ่มต้นโปรเจกต์ Spring WebFlux
1. ใช้ Spring Initializr
- ไปที่ https://start.spring.io
- เลือก Spring Boot >= 3.0
- เลือก dependency:
Spring Reactive Web
,Lombok
2. ตัวอย่างโครงสร้างโปรเจกต์
src/
└── main/
├── java/
│ └── com.example.webflux/
│ ├── controller/
│ ├── model/
│ ├── repository/
│ ├── service/
│ └── WebFluxApp.java
└── resources/
└── application.yml
ตัวอย่าง: สร้าง REST API แบบ Reactive
Model
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "products")
public class Product {
@Id
private String id;
private String name;
private Double price;
}
Repository
public interface ProductRepository extends ReactiveMongoRepository<Product, String> {
Flux<Product> findByPriceBetween(double min, double max);
}
Controller
@RestController
@RequestMapping("/products")
public class ProductController {
@Autowired
private ProductRepository repo;
@GetMapping
public Flux<Product> getAll() {
return repo.findAll();
}
@GetMapping("/{id}")
public Mono<Product> getById(@PathVariable String id) {
return repo.findById(id);
}
@PostMapping
public Mono<Product> create(@RequestBody Product p) {
return repo.save(p);
}
@DeleteMapping("/{id}")
public Mono<Void> delete(@PathVariable String id) {
return repo.deleteById(id);
}
}
Reactive Type: Mono และ Flux
- Mono<T>: ส่งค่าเดียว หรือ error หรือ empty
- Flux<T>: ส่งหลายค่า (stream) หรือ empty/error
ตัวอย่าง:
Mono.just("Hello").subscribe(System.out::println);
Flux.range(1, 5).subscribe(System.out::println);
Server-Sent Events (SSE) ใน WebFlux
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> stream() {
return Flux.interval(Duration.ofSeconds(1))
.map(i -> "Message #" + i);
}
Spring WebFlux กับ Functional Endpoint
นอกจากใช้ @RestController แล้ว WebFlux ยังรองรับ “Functional Style Routing”
Handler Function
public class ProductHandler {
public Mono<ServerResponse> hello(ServerRequest req) {
return ServerResponse.ok().bodyValue("Hello from functional route");
}
}
Router Config
@Configuration
public class RouterConfig {
@Bean
public RouterFunction<ServerResponse> route(ProductHandler handler) {
return RouterFunctions
.route(GET("/hello"), handler::hello);
}
}
การทำ Unit Test ใน WebFlux
@WebFluxTest(ProductController.class)
public class ProductControllerTest {
@Autowired
private WebTestClient webClient;
@Test
void testGetAll() {
webClient.get().uri("/products")
.exchange()
.expectStatus().isOk()
.expectBodyList(Product.class);
}
}
การ Deploy Spring WebFlux
1. สร้าง Jar
./mvnw clean package
2. Run บน Docker
FROM eclipse-temurin:17
WORKDIR /app
COPY target/webflux-demo.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
3. สร้าง image
docker build -t webflux-demo .
docker run -p 8080:8080 webflux-demo
4. Deploy บน Kubernetes / Cloud
- สามารถใช้ Helm, YAML หรือ Spring Cloud Kubernetes
- เหมาะกับ workload ที่มีการ connect หลาย client พร้อมกัน
Use Cases ที่เหมาะกับ Spring WebFlux
- Streaming, Notification, Live data feed
- ระบบ IoT ที่มี sensor จำนวนมาก
- ระบบที่ต้องการ scale ตาม request concurrency
- WebSocket และ SSE
บทสรุป
Spring WebFlux คือคำตอบสำหรับการพัฒนาแอปพลิเคชันแบบ reactive ที่สามารถ scale ได้ดีในระบบ cloud-native โดยเฉพาะ use case ที่มี request concurrency สูง หรือระบบที่เน้น streaming
แม้ว่า WebFlux จะมีความซับซ้อนในการเรียนรู้ แต่เมื่อเข้าใจและใช้อย่างถูกต้องจะช่วยให้ระบบมีประสิทธิภาพสูงมาก ทั้งในเรื่องของ memory, throughput และ response time ที่ดีขึ้นอย่างชัดเจน