import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/vi/functional-basic/Classes/ApiResponse - Giả lập phản hồi API'/>

# Lớp ApiResponse

Một lớp quản lý để chặn, lưu trữ và giả lập các phản hồi API. Nó cho phép bạn chặn các yêu cầu API đi và trả về dữ liệu mẫu (mock data) đã được định nghĩa trước thay vì kích hoạt lưu lượng mạng thực tế.

> `ApiResponse` là một **lớp bổ trợ** (auxiliary class), được thiết kế để giả lập và tạo mock API. Trong hầu hết các trường hợp, bạn nên đăng ký các phản hồi mock thông qua tham số `response` trong cấu hình `Api` toàn cục.

## Các tính năng chính

- **Chặn yêu cầu** — khớp các yêu cầu đi một cách thông minh dựa trên đường dẫn mục tiêu, phương thức HTTP và đối tượng dữ liệu.
- **Khả năng linh hoạt** — hỗ trợ cả các đối tượng tĩnh được định nghĩa trước hoặc thực thi các logic callback động có khả năng diễn giải ngữ cảnh yêu cầu.
- **Mô phỏng độ trễ mạng** — hệ thống tích hợp được thiết kế riêng để mô phỏng các kịch bản độ trễ thực tế (bộ hẹn giờ bù ngẫu nhiên).
- **Chế độ nhà phát triển** — in các thông tin gỡ lỗi hữu ích trong console trình duyệt cho biết dữ liệu nào đã khớp trực tiếp với một điểm mock cụ thể.

## Khởi tạo

Để khởi tạo đối tượng, hãy gọi hàm dựng `ApiResponse(requestDefault)`.

**Tham số:**
- `requestDefault: ApiDefault` — lớp yêu cầu mặc định được sử dụng để cấu hình và lưu trữ.

```typescript
import { ApiResponse } from '@dxtmisha/functional-basic'

const apiResponse = new ApiResponse(myApiDefault)
```

## Các phương thức

### Hành động

#### `emulator`

Vòng lặp công cụ chính để xác thực các cấu hình yêu cầu và thực thi các phản hồi mock có độ trễ tương ứng. Phương thức này chỉ chạy trong môi trường DOM.

**Tham số:**
- `apiFetch: ApiFetch` — Các thuộc tính của yêu cầu cần giả lập.

**Trả về:** `Promise<T | undefined>` — Dữ liệu phản hồi đã giả lập.

#### `emulatorAsync`

Phiên bản đồng bộ của trình giả lập. Nó trả về phản hồi mock ngay lập tức mà không có bất kỳ độ trễ hoặc trạng thái tải nào. Phương thức này chỉ chạy trong môi trường DOM.

**Tham số:**
- `apiFetch: ApiFetch` — Các thuộc tính của yêu cầu cần giả lập.

**Trả về:** `T | undefined` — Dữ liệu phản hồi đã giả lập.

### Kiểm tra

- `get(path: string, method: ApiMethod, request?: ApiFetch['request'], devMode?: boolean): ApiResponseItem | undefined` — Kiểm tra đồng bộ một yêu cầu mock đã lưu khớp với các tham số.
- `getList(): (ApiResponseItem & Record<string, any>)[]` — Trả về danh sách tất cả các cấu hình giả lập đã đăng ký.

### Cấu hình

- `add(response: ApiResponseItem | ApiResponseItem[]): this` — Thêm các đối tượng phản hồi mock vào bộ đăng ký cục bộ.
- `setDevMode(devMode: boolean): this` — Bật/tắt chế độ nhật ký gỡ lỗi phát triển.

## Các kiểu dữ liệu

#### `ApiResponseItem`
Một đối tượng định nghĩa cấu hình phản hồi mock.
- `path: string | RegExp` — Đường dẫn hoặc mẫu URL khớp.
- `method: ApiMethod` — Phương thức HTTP (GET, POST, v.v.).
- `response: any | ((request?: any) => any)` — Dữ liệu mock hoặc hàm trả về dữ liệu đó.
- `request?: ApiFetch['request'] | '*any'` — Dữ liệu yêu cầu tùy chọn để khớp.
- `lag?: boolean` — Có mô phỏng độ trễ mạng hay không.
- `disable?: any` — Điều kiện để vô hiệu hóa mock (boolean hoặc hàm).
- `isForGlobal?: boolean` — Đánh dấu là mock toàn cục (ẩn khỏi getList).

## Hướng dẫn: Giả lập API

Các quy tắc và điều kiện sau đây xác định cách hệ thống giả lập chặn và tạo mock cho các yêu cầu mạng:

- **Đăng ký Mock** — các phản hồi được thêm qua `add()` sẽ được ưu tiên và kiểm tra trước khi bất kỳ cuộc gọi mạng thực tế nào được khởi tạo.
- **Tiêu chí khớp** — một mock chỉ được kích hoạt nếu đường dẫn (chuỗi hoặc RegExp), phương thức HTTP và nội dung yêu cầu đều khớp với cấu hình.
- **Ký tự đại diện cho Body** — sử dụng `*any` làm giá trị yêu cầu cho phép mock khớp với bất kỳ payload nào, bỏ qua việc so sánh đối tượng chuyên sâu.
- **Dữ liệu động** — thuộc tính `response` có thể là một hàm, cho phép bạn tạo dữ liệu mock động dựa trên các tham số yêu cầu đầu vào.
- **Mô phỏng độ trễ** — thiết lập `lag: true` sẽ thêm một khoảng trễ ngẫu nhiên (0-2000ms) và kích hoạt trạng thái tải chung (lớp `d-response-loading` trên body).
- **Tính duy trì của khớp** — theo mặc định, một cấu hình giả lập chỉ khớp một lần trừ khi `devMode` được bật, điều này ngăn chặn việc kích hoạt mock trùng lặp cho cùng một trạng thái.
