82 lines
3.4 KiB
Markdown
82 lines
3.4 KiB
Markdown
---
|
||
name: springboot-patterns
|
||
description: Spring Boot 架構模式,涵蓋 REST API 設計、分層服務、資料存取、快取、非同步處理及紀錄。適用於 Java Spring Boot 後端開發。
|
||
---
|
||
|
||
# Spring Boot 開發模式 (Spring Boot Development Patterns)
|
||
|
||
用於建構具備可擴展性、生產等級服務的 Spring Boot 架構與 API 模式。
|
||
|
||
## 何時啟用
|
||
|
||
- 使用 Spring MVC 或 WebFlux 建立 REST API。
|
||
- 規劃 Controller → Service → Repository 的分層架構。
|
||
- 配置 Spring Data JPA、快取 (Caching) 或非同步處理 (Async)。
|
||
- 添加資料驗證 (Validation)、例外處理 (Exception Handling) 或分頁功能。
|
||
- 為開發/測試/生產環境設置不同的 Profiles。
|
||
- 實作基於事件驅動的模式(使用 Spring Events 或 Kafka)。
|
||
|
||
## REST API 結構範例
|
||
|
||
```java
|
||
@RestController
|
||
@RequestMapping("/api/markets")
|
||
@Validated
|
||
class MarketController {
|
||
private final MarketService marketService;
|
||
|
||
MarketController(MarketService marketService) {
|
||
this.marketService = marketService;
|
||
}
|
||
|
||
@GetMapping
|
||
ResponseEntity<Page<MarketResponse>> list(
|
||
@RequestParam(defaultValue = "0") int page,
|
||
@RequestParam(defaultValue = "20") int size) {
|
||
Page<Market> markets = marketService.list(PageRequest.of(page, size));
|
||
return ResponseEntity.ok(markets.map(MarketResponse::from));
|
||
}
|
||
|
||
@PostMapping
|
||
ResponseEntity<MarketResponse> create(@Valid @RequestBody CreateMarketRequest request) {
|
||
Market market = marketService.create(request);
|
||
return ResponseEntity.status(HttpStatus.CREATED).body(MarketResponse.from(market));
|
||
}
|
||
}
|
||
```
|
||
|
||
## Repository 與 Service 模式
|
||
|
||
- **Repository**:繼承 `JpaRepository` 並利用 Spring Data JPA 的方法命名約定或 `@Query`。
|
||
- **Service**:處理業務邏輯,並使用 `@Transactional` 確保資料一致性。
|
||
|
||
## 例外處理 (Global Exception Handling)
|
||
|
||
使用 `@ControllerAdvice` 統一收斂系統異常,並回傳格式化後的錯誤回應 (如 `ResponseEntity<ApiError>`)。
|
||
|
||
## 快取與非同步處理
|
||
|
||
- **快取**:在配置類標註 `@EnableCaching`,並在 Service 方法上使用 `@Cacheable` 或 `@CacheEvict`。
|
||
- **非同步**:標註 `@EnableAsync`,使用 `@Async` 標註方法並回傳 `CompletableFuture`。
|
||
|
||
## 紀錄 (SLF4J)
|
||
|
||
優先使用構造函數注入 Logger 或使用 Lombok 的 `@Slf4j`。確保在關鍵業務節點紀錄階段性資訊,並在 Catch 塊中記錄完整堆疊 (Stack Trace)。
|
||
|
||
## 速率限制 (Rate Limiting)
|
||
|
||
使用 Filter 結合 Bucket4j 實作。
|
||
**安全性提醒**:若應用部署在反向代理(如 Nginx, AWS ALB)後方,必須配置 `server.forward-headers-strategy` 以正確獲取客戶端真實 IP,避免 Rate Limiter 被偽造的 `X-Forwarded-For` 繞過。
|
||
|
||
## 生產環境最佳實踐
|
||
|
||
- **依賴注入**:優先採用構造函數注入 (Constructor Injection),避免欄位注入 (Field Injection)。
|
||
- **資料庫連接池**:根據負載調整 HikariCP 參數。
|
||
- **事務管理**:對於純查詢方法,使用 `@Transactional(readOnly = true)`。
|
||
- **回應格式**:Spring Boot 3+ 建議啟用 `spring.mvc.problemdetails.enabled=true` 以符合 RFC 7807 標準。
|
||
- **可觀察性**:整合 Micrometer、Prometheus 與 OpenTelemetry 進行指標監控與鏈路追蹤。
|
||
|
||
---
|
||
|
||
**核心原則**:保持 Controller 輕量、Service 職責明確、Repository 邏輯單純,並將錯誤處理機制中心化。
|