Đọc hết dữ liệu LarkBase bằng n8n: xử lý has_more và page_token cho đúng

@Nguyễn Ngô Thượng//~5 phút đọc0
Chia sẻ:

TL;DR: LarkBase trả dữ liệu theo trang. Gọi API một lần chỉ được vài chục dòng đầu, phần còn lại nằm ở các trang sau. Dùng page_token để đi tiếp, dừng khi has_more = false. Trong n8n, node HTTP Request có sẵn cơ chế pagination nên không phải tự dựng vòng lặp — nhưng phải đặt page_size lớn hơn 0, nếu không luồng chạy loạn.

Vì sao lấy dữ liệu về mà thiếu dòng

Lỗi này gặp ngay lần đầu tự động hoá LarkBase: bảng có 800 dòng, workflow chạy xong chỉ thấy 20 dòng. Không phải n8n hỏng, cũng không phải mất quyền — đó là phân trang.

Khi bảng nhiều dữ liệu, LarkBase không trả hết trong một response. Nó cắt thành từng trang và đưa cho bạn một cái "vé" để lấy trang kế tiếp. Không cầm vé đi tiếp thì dừng ở trang đầu.

Đây là bước nền. Mọi thứ phía sau — đối soát, upsert, dựng báo cáo — đều sai nếu dữ liệu đầu vào thiếu dòng, mà kiểu sai này rất khó phát hiện: báo cáo vẫn chạy, số vẫn ra, chỉ là số sai.

has_more và page_token là gì

Mỗi lần gọi API lấy bản ghi, response trả về kèm hai trường quan trọng:

Trường Kiểu Ý nghĩa
has_more boolean Còn dữ liệu ở trang sau hay không
page_token string "Vé" để lấy trang tiếp theo

Cơ chế chạy như sau:

  1. Gọi lần đầu không kèm page_token → nhận một trang dữ liệu, kèm page_token mới và has_more.
  2. Nếu has_more = true → gọi tiếp, lần này đính kèm page_token vừa nhận.
  3. Lặp cho tới khi has_more = false. Lúc đó bạn mới có đủ dữ liệu.

Response rút gọn trông như thế này:

{
  "code": 0,
  "data": {
    "has_more": true,
    "page_token": "cGFnZV90b2tlbjoxMjM0NQ",
    "total": 823,
    "items": [
      { "record_id": "recXXXXXXXX", "fields": { "Mã đơn": "8051" } }
    ]
  }
}

Dựng trong n8n: để HTTP Request tự phân trang

Đây là chỗ n8n dễ chịu hơn hẳn so với việc tự dựng biến và vòng lặp bằng tay. Node HTTP Request có sẵn mục Pagination — bạn khai báo cách đi tiếp và điều kiện dừng, node tự gọi lặp rồi gộp kết quả.

Bước 1: Cấu hình request

Method POST, URL endpoint search của bảng cần đọc. page_sizepage_tokenquery parameter trên URL (ví dụ ?page_size=500&page_token=...) — lần gọi đầu không kèm page_token. Body chỉ chứa filter, sort hay field_names nếu cần.

Bước 2: Bật Pagination

Trong phần Options → Pagination, chọn kiểu cập nhật tham số theo mỗi lần gọi, rồi gán query parameter page_token (không phải body) bằng giá trị lấy từ response trước đó.

Bước 3: Đặt điều kiện dừng

Điều kiện hoàn tất là khi has_more không còn true. Thiếu bước này thì node gọi mãi.

Hai biểu thức cần dùng:

// Giá trị page_token cho lần gọi kế tiếp
{{ $response.body.data.page_token }}

// Điều kiện dừng phân trang
{{ $response.body.data.has_more === false }}

Nếu muốn tự kiểm soát hoàn toàn thay vì dùng pagination có sẵn, dùng Loop Over Items kết hợp node Code để tích luỹ. Nhưng với đa số bảng, cách trên đủ và ít chỗ sai hơn.

Cái bẫy: page_size phải lớn hơn 0

Lần đầu dựng luồng này, workflow của tôi chạy loạn và không bao giờ dừng. Nguyên nhân rất tầm thường: page_size để trống.

Khi bỏ hẳn tham số này, API mặc định trả 20 dòng mỗi trang — không sao cả. Vấn đề xảy ra khi n8n gửi page_size rỗng hoặc không hợp lệ trong request: mỗi vòng trả về không đúng như kỳ vọng, has_more không bao giờ chuyển sang false, và vòng lặp cứ thế chạy. Nên luôn đặt một con số cụ thể.

⚠️ Warning: Luôn đặt page_size một con số cụ thể. Bảng nhỏ để 100, bảng lớn để 500 cho đỡ số vòng gọi. Đồng thời đặt giới hạn số trang tối đa — vòng lặp vô hạn trên một API có tính phí là kiểu lỗi tốn tiền thật.

Kiểm lại xem đã lấy đủ chưa

Đừng tin cảm giác. Ba cách kiểm nhanh:

  • So total với số item gộp được. Response có sẵn total — số item cuối cùng phải khớp.
  • Soi missing value ở vài cột chính. Nếu một cột đột nhiên trống ở phần cuối dữ liệu, khả năng cao là rớt trang giữa chừng.
  • Chạy lại lần hai. Số bản ghi phải giống hệt lần một. Lệch nghĩa là logic phân trang đang phụ thuộc thứ tự trả về.

Đừng quên xử lý lỗi

Đây là phần n8n có mà cách làm cũ trên nền tảng automation trong hệ Lark không có: mỗi node đều bật được retry on fail, và cả workflow gắn được error workflow để báo về nhóm chat khi hỏng.

Bảng 5.000 dòng nghĩa là 10 lần gọi API liên tiếp. Chỉ cần một lần rớt mạng là mất trắng cả lượt chạy nếu không có retry. Đặt retry 3 lần, chờ vài giây giữa các lần — rẻ hơn nhiều so với việc sáng hôm sau phát hiện báo cáo thiếu dữ liệu.

Khi nào cần làm cho chuẩn

Bảng dưới 100 dòng và chỉ đọc thủ công thì bỏ qua cũng được. Nhưng nếu dữ liệu này là đầu vào của đối soát, upsert dữ liệu vào LarkBase hay báo cáo cho lãnh đạo, thì phân trang là thứ bắt buộc phải đúng ngay từ đầu — vì hậu quả không hiện ra dưới dạng lỗi, mà dưới dạng con số sai.

ℹ️ Info: Trước đây tôi dựng luồng này bằng AnyCross. Từ 2026 chuyển sang n8n vì ba lý do thực tế: tự host được nên dữ liệu không đi qua bên thứ ba, xem được log từng node khi cần lần lỗi, và không tính tiền theo lượt chạy.

Tự làm mất bao lâu

Để bạn ước lượng trước khi bắt tay:

Việc Người đã quen n8n Người mới
Dựng luồng đọc hết dữ liệu một bảng 1–2 giờ nửa ngày đến 1 ngày
Thêm retry và cảnh báo lỗi 30 phút nửa ngày
Dựng server n8n và giữ nó chạy ổn định vài giờ 2–3 ngày, cộng chi phí học

Riêng luồng đọc dữ liệu thì tự làm hoàn toàn hợp lý — đây là phần dễ nhất. Phần tốn thời gian thật nằm ở chỗ khác: dựng và duy trì hạ tầng, và xử lý khi luồng hỏng lúc bạn đang bận việc khác.

Nếu đây là dữ liệu để đối soát hoặc báo cáo cho lãnh đạo — thứ sai một hôm là biết ngay — thì thuê dựng trọn gói thường rẻ hơn tự mò, tính cả thời gian của bạn.

Xem dịch vụ automation →

Bài viết hữu ích?

Chia sẻ để nhiều người biết đến!

Chia sẻ:

>_ LLM-Friendly Copy

Copy as Markdown to use with ChatGPT, Claude, or other AI tools

1,202 words|6,095 characters

//Bình luận

Bài viết liên quan

Khám phá thêm những bài viết cùng chủ đề với Đọc hết dữ liệu LarkBase bằng n8n: xử lý has_more và page_token cho đúng

Bài viết hữu ích? Hãy kết nối với Diginno!

Chúng tôi giúp doanh nghiệp SME ứng dụng AI và automation vào quy trình làm việc - từ tư vấn chiến lược đến triển khai thực tế.

Đọc hết dữ liệu LarkBase bằng n8n: xử lý has_more và page_token cho đúng | Blog - Diginno