> For the complete documentation index, see [llms.txt](https://docs.verge.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.verge.io/knowledge-base/vi/storage-vsan/nas-volume-browser-api.md).

# Tài liệu tham khảo API Trình duyệt Volume NAS

## Tổng quan

{% hint style="info" %}
**Các điểm chính**

* API volume\_browser là **bất đồng bộ** - tạo một job, rồi thăm dò kết quả
* Bạn **phải** bao gồm `?fields=id,status,result` khi thăm dò, nếu không kết quả sẽ không được trả về
* Dùng chuỗi rỗng `""` cho đường dẫn thư mục gốc (không `/`)
* VM dịch vụ NAS phải đang chạy để duyệt các volume
  {% endhint %}

Tham số `volume_browser` API cung cấp khả năng duyệt hệ thống tệp cho các volume NAS. Điều này hữu ích cho tự động hóa, tích hợp và xây dựng các công cụ quản lý tệp tùy chỉnh.

## Điều kiện tiên quyết

* Một dịch vụ NAS đang chạy với ít nhất một volume trực tuyến
* Quyền truy cập API với quyền phù hợp
* Mã định danh khóa SHA1 của volume (tìm trong URL bảng điều khiển volume hoặc API)

## Cách hoạt động

Duyệt một volume là quy trình hai bước:

1. **POST** sang `/api/v4/volume_browser` để tạo một job duyệt
2. **GET** sang `/api/v4/volume_browser/{job_id}?fields=id,status,result` để thăm dò kết quả

## Bước 1: Tạo yêu cầu duyệt

### Endpoint

```
POST /api/v4/volume_browser
```

### Phần thân yêu cầu

```json
{
  "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
  "query": "get-dir",
  "params": {
    "dir": "",
    "limit": 1000,
    "offset": null,
    "filter": {
      "extensions": ""
    },
    "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
    "sort": ""
  }
}
```

### Tham chiếu trường

| Trường   | Loại      | Bắt buộc | Mô tả                                                |
| -------- | --------- | -------- | ---------------------------------------------------- |
| `volume` | chuỗi     | Có       | Khóa volume (mã định danh băm SHA1)                  |
| `query`  | chuỗi     | Có       | Loại thao tác: `get-dir`, `đổi tên`, `delete`, `dán` |
| `params` | đối tượng | Có       | Tham số truy vấn (xem bên dưới)                      |

### Đối tượng tham số

| Trường              | Loại           | Mô tả                                                  |
| ------------------- | -------------- | ------------------------------------------------------ |
| `dir`               | chuỗi          | Đường dẫn thư mục để duyệt. Dùng `""` cho thư mục gốc. |
| `limit`             | số nguyên      | Số mục tối đa trả về (ví dụ, 1000)                     |
| `offset`            | số nguyên/null | Vị trí offset phân trang, `null` cho trang đầu tiên    |
| `filter.extensions` | chuỗi          | Lọc theo phần mở rộng tệp (chuỗi rỗng cho tất cả)      |
| `volume`            | chuỗi          | Khóa volume (phải khớp với cấp cao nhất `volume`)      |
| `sort`              | chuỗi          | Trường sắp xếp (chuỗi rỗng cho mặc định)               |

### Phản hồi

```json
{
  "location": "/v4/volume_browser/9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "dbpath": "volume_browser/9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "$row": 1,
  "$key": "9a00434b882b9933512cc9d3abfd557a182d8fd3"
}
```

Tham số `$key` trường chứa ID job cần cho việc thăm dò.

## Bước 2: Thăm dò kết quả

### Endpoint

```
GET /api/v4/volume_browser/{job_id}?fields=id,status,result
```

{% hint style="danger" %}
**Quan trọng: Yêu cầu trường result**

Tham số `result` trường là **KHÔNG được trả về theo mặc định**. Bạn phải yêu cầu rõ ràng bằng `?fields=id,status,result`. Nếu không có tham số này, bạn sẽ chỉ nhận được thông tin trạng thái.
{% endhint %}

**Nếu không có `?fields=id,status,result`:**

```json
{
  "id": "9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "query": "get-dir",
  "status": "complete",
  "command": ""
}
```

**Với `?fields=id,status,result`:**

```json
{
  "id": "9a00434b882b9933512cc9d3abfd557a182d8fd3",
  "status": "complete",
  "result": [
    {"name": "documents", "size": 4096, "date": 1706120819, "type": "directory"},
    {"name": "file.txt", "size": 1024, "date": 1769198797, "type": "file"}
  ]
}
```

### Giá trị trạng thái

| ô          | Mô tả                                                 |
| ---------- | ----------------------------------------------------- |
| `running`  | Job vẫn đang xử lý                                    |
| `complete` | Job hoàn tất thành công                               |
| `error`    | Job thất bại (kiểm tra `result` để xem thông báo lỗi) |

### Chiến lược thăm dò

```
1. POST để tạo job
2. Chờ 200-500ms
3. GET với ?fields=id,status,result
4. Nếu status == "running", chờ và thử lại (tối đa 30 lần)
5. Nếu status == "complete", xử lý kết quả
6. Nếu status == "error", xử lý lỗi
```

## Định dạng kết quả

Khi `status` là `complete`, thì `result` trường chứa một mảng các mục tệp/thư mục:

```json
[
  {
    "name": "document.pdf",
    "n_name": "document.pdf",
    "size": 102400,
    "date": 1769136871,
    "type": "file"
  },
  {
    "name": "images",
    "n_name": "images",
    "size": 4096,
    "date": 1769197982,
    "type": "directory"
  }
]
```

### Các trường mục

| Trường   | Loại      | Mô tả                                  |
| -------- | --------- | -------------------------------------- |
| `name`   | chuỗi     | Tên tệp hoặc thư mục                   |
| `n_name` | chuỗi     | Tên chuẩn hóa (chữ thường)             |
| `size`   | số nguyên | Kích thước tính bằng byte              |
| `date`   | số nguyên | Thời gian sửa đổi (dấu thời gian Unix) |
| `type`   | chuỗi     | `"file"` hoặc `"directory"`            |

### Thư mục trống

Đối với thư mục trống, `result` sẽ là một mảng rỗng:

```json
{
  "id": "8cb12559b689f5a52472bd8882dde1c095b2ab64",
  "status": "complete",
  "result": []
}
```

## Ví dụ

### cURL

```bash
# Bước 1: Tạo job duyệt
JOB_ID=$(curl -s -X POST "https://your-vergeos.example.com/api/v4/volume_browser" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
    "query": "get-dir",
    "params": {
      "dir": "",
      "limit": 1000,
      "offset": null,
      "filter": {"extensions": ""},
      "volume": "62db5fcd888082246b9346c0e65311334d91ed2c",
      "sort": ""
    }
  }' | jq -r '."$key"')

# Bước 2: Thăm dò kết quả (QUAN TRỌNG: bao gồm tham số fields)
sleep 1
curl -s "https://your-vergeos.example.com/api/v4/volume_browser/${JOB_ID}?fields=id,status,result" \
  -H "Authorization: Bearer $TOKEN" | jq
```

### Python

```python
import requests
import time

def browse_volume(base_url, token, volume_key, path=""):
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }

    # Bước 1: Tạo job duyệt
    payload = {
        "volume": volume_key,
        "query": "get-dir",
        "params": {
            "dir": path,  # Dùng "" cho thư mục gốc
            "limit": 1000,
            "offset": None,
            "filter": {"extensions": ""},
            "volume": volume_key,
            "sort": ""
        }
    }

    response = requests.post(
        f"{base_url}/api/v4/volume_browser",
        headers=headers,
        json=payload,
        verify=False
    )
    job_id = response.json()["$key"]

    # Bước 2: Thăm dò kết quả
    for _ in range(30):
        time.sleep(0.5)

        # QUAN TRỌNG: Yêu cầu rõ ràng trường result
        response = requests.get(
            f"{base_url}/api/v4/volume_browser/{job_id}?fields=id,status,result",
            headers=headers,
            verify=False
        )
        data = response.json()

        if data["status"] == "complete":
            return data.get("result") or []
        elif data["status"] == "error":
            raise Exception(f"Browse failed: {data.get('result')}")

    raise TimeoutError("Browse operation timed out")
```

## Khắc phục sự cố

{% hint style="warning" %}
**Các sự cố thường gặp**

**Trường result trống hoặc bị thiếu**

* Bạn phải bao gồm `?fields=id,status,result` trong yêu cầu GET của bạn
* Nếu không có tham số này, chỉ thông tin trạng thái được trả về

**"VM must be in running state to issue a query"**

* VM dịch vụ NAS không đang chạy
* Đi tới NAS > NAS Services và khởi động dịch vụ

**"Error getting volumes VM service: No such file or directory"**

* Dịch vụ NAS của volume không tồn tại hoặc đã bị xóa
* Xác minh volume được liên kết với một dịch vụ NAS hợp lệ

**"Resource '/v4/volume\_browser/' not found"**

* ID job rỗng trong yêu cầu thăm dò
* Đảm bảo bạn trích xuất `$key` đúng cách từ phản hồi POST
  {% endhint %}

### Các lỗi thường gặp

1. **Sử dụng `path` thay vì `dir`** - Trường được đặt tên là `dir`, không phải `path`
2. **Gửi params dưới dạng chuỗi JSON** - Trường `params` phải là một đối tượng, không phải chuỗi được mã hóa JSON
3. **Thiếu các trường params** - Tất cả các trường trong đối tượng params đều được mong đợi
4. **Quên `?fields=id,status,result`** - Nếu không có điều này, sẽ không có dữ liệu tệp nào được trả về

## Yêu cầu

* VM dịch vụ NAS phải đang chạy để duyệt các volume
* Volume phải ở trạng thái trực tuyến (đã được gắn)
* Người dùng phải có quyền đọc trên volume

## Tài nguyên bổ sung

* [Tổng quan NAS](/run-the-platform/nas/overview.md)
* [Các volume cục bộ NAS](/run-the-platform/nas/nas-local-volumes.md)
* [Khóa API](/run-the-platform/system-administration/api-keys.md)

## Phản hồi

{% hint style="info" %}
**Cần trợ giúp?**

Nếu bạn cần thêm hỗ trợ hoặc có bất kỳ câu hỏi nào về bài viết này, vui lòng đừng ngần ngại liên hệ với [Đội ngũ Hỗ trợ VergeOS](/support-and-services.md).
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.verge.io/knowledge-base/vi/storage-vsan/nas-volume-browser-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
