# API Version

Bạn đang muốn **100% request vào chung 1 API v1**, nhưng chia trách nhiệm khác nhau:

* **90% request**: xử lý theo business logic bình thường (ví dụ: use case chính).
* **10% request**: cũng đi vào API v1 nhưng có logic hoặc trách nhiệm khác (ví dụ: logging nâng cao, A/B testing, shadow traffic, canary...).

Cách làm trong backend có thể chia thành mấy hướng:

***

### 1. Random routing trong chính API v1

Bạn có thể implement random split ngay trong handler:

```go
func HandlerV1(w http.ResponseWriter, r *http.Request) {
    rand.Seed(time.Now().UnixNano())
    if rand.Intn(100) < 10 {
        // 10% request
        handleSpecialCase(w, r)
        return
    }
    // 90% request
    handleNormalCase(w, r)
}
```

* Ưu điểm: đơn giản, không cần thay đổi kiến trúc.
* Nhược điểm: khó theo dõi nếu muốn rollback nhanh hoặc tracking riêng.

***

### 2. Sử dụng Gateway / Load Balancer

Nếu bạn có API Gateway (Spring Cloud Gateway, Nginx, Kong, Envoy...), có thể cấu hình rule:

* 90% request route tới **service-v1-normal**
* 10% request route tới **service-v1-special**\
  → Hai service này có thể reuse cùng code base nhưng chạy với config khác (ví dụ bật flag xử lý riêng).

Cách này thường dùng khi triển khai **canary release hoặc A/B testing**.

***

### 3. Feature Flag / Experiment Framework

Dùng 1 framework như:

* **LaunchDarkly**, **Unleash**, hoặc tự build feature-flag table trong DB.
* Trong API v1, kiểm tra feature flag theo userID, sessionID, hoặc requestID → quyết định vào nhóm 90% hay 10%.

Ví dụ:

```go
if featureFlagService.IsInExperiment(userID, "experiment_v1_10_percent") {
    handleSpecialCase(w, r)
} else {
    handleNormalCase(w, r)
}
```

Cách này tốt hơn random vì bạn **giữ consistency** (cùng user thì lần nào cũng rơi vào nhóm 10%).

***

### 4. Shadow Traffic (nếu chỉ cần thử nghiệm)

Nếu bạn muốn 100% request vẫn xử lý như cũ, nhưng **10% request sẽ được clone thêm và đẩy sang service khác** để test:

* Nginx / Envoy / Istio hỗ trợ **mirror traffic**.
* Request chính vẫn trả về từ service cũ, nhưng bạn có bản copy để chạy thử service mới.

***

✅ **Lời khuyên thực tế**:

* Nếu chỉ muốn chia trách nhiệm trong cùng 1 service → dùng **random routing trong handler** hoặc **feature flag**.
* Nếu muốn kiểm soát deployment (canary, rollback nhanh) → dùng **Gateway/LB routing**.
* Nếu muốn thử nghiệm nhưng không ảnh hưởng người dùng → dùng **shadow traffic**.
