Kestra workflow tải API: input, artifact và truy vết execution
Kestra workflow tải API là cách mô tả việc tải dữ liệu từ một API được phép bằng YAML: input, task, trigger, output đều nằm trong một tệp. Tài sản cần có là execution chứa URL nguồn và artifact cuối. ProxyVN viết flow theo tài liệu, chạy nó qua một trình mô phỏng nhỏ trên fixture cục bộ, thử lỗi có kiểm soát, và ghi rõ flow chưa được Kestra thật kiểm tra.
Kestra workflow tải API: mục tiêu và phạm vi không lặp
Phần này chốt bài toán, đầu ra và giới hạn.
Bài toán cần giải
Một nhóm tải dữ liệu danh mục từ API đối tác mỗi giờ. Script chạy bằng cron, lỗi thì không ai biết, tệp kết quả không rõ đến từ lần chạy nào. Khi đối tác hỏi số liệu ngày hôm qua lấy từ URL nào, nhóm không trả lời được. Họ muốn mỗi lần chạy có một mã, biết đầu vào, biết tệp đầu ra.
Đầu ra nghiệm thu
Đầu ra là YAML workflow và output của execution chứa URL nguồn cùng artifact cuối. Từ một execution ID, anh em truy được input, tệp thô và tệp đã xử lý. Kèm theo là ca lỗi có kiểm soát: API 503, dữ liệu thiếu trường, input sai kiểu.
Ranh giới với bài Dagster
Bài Dagster asset nói về đồ thị tài sản viết bằng Python. Bài này nói về flow khai báo bằng YAML, với execution và artifact là đơn vị truy vết. Bài không chuyển nguyên pipeline Dagster sang YAML. Điểm riêng ở đây là input có kiểu, output theo task và internal storage.
Giới hạn của lab
Nói rõ ngay. Lab không chạy Kestra thật. Kestra cần máy chủ Java và Docker cho script task, máy lab không tải được. ProxyVN viết một trình chạy Python rất nhỏ, đọc đúng tệp flow.yml bằng PyYAML. Nó kiểm tra input, thay biểu thức cho ba task của flow, tải từ fixture cục bộ, rồi lưu tệp vào một thư mục đóng vai internal storage.
Thứ gì thật, thứ gì giả
Tệp YAML là thật, viết theo tài liệu Kestra, nhưng chưa được Kestra kiểm tra hợp lệ. HTTP tới fixture là thật. Trạng thái SUCCESS, FAILED, RETRYING, nhánh errors, cơ chế thử lại đều do trình mô phỏng của ProxyVN làm theo tài liệu. Đường dẫn kestra:/// trong output là chuỗi mô phỏng.
Đọc kết quả thế nào
Lab giúp kiểm tra thiết kế luồng: dữ liệu đi từ task nào tới task nào, thiếu gì thì không truy vết được, lỗi rơi vào đâu. Nó không chứng minh tên thuộc tính đúng với phiên bản Kestra của anh em, cũng không cho biết thời gian chạy. Trước khi dùng, hãy dán flow vào editor của Kestra để nó báo lỗi cú pháp.
Ai nên đọc bài này
Người muốn đưa script tải API vào một công cụ điều phối có giao diện. Người cần truy vết mỗi tệp dữ liệu về lần chạy cụ thể. Người chưa quen Kestra và muốn thấy một flow đủ phần, không chỉ hello world.
Biểu diễn trigger, input, output của Kestra workflow tải API được phép
Phần này tóm tắt tài liệu chính thức.
Các thành phần của một flow

Các khối của flow
Trang Workflow Components liệt kê các khối: flow, task, namespace, execution, variables, inputs, outputs, triggers, errors, retries và các phần khác. Một flow có id, namespace và danh sách tasks. Mọi thứ khác là tùy chọn, và bài chỉ dùng những gì cần cho bài toán.
Khối |
Vai trò trong bài này |
|---|---|
inputs |
Tham số có kiểu của mỗi lần chạy |
tasks |
Tải, xử lý, ghi manifest |
outputs của task |
Truyền URI và giá trị xuống task sau |
errors |
Nhánh xử lý khi có task lỗi |
triggers |
Lịch chạy tự động |
retry |
Thử lại task tải |
Namespace để làm gì
Namespace gom các flow theo nhóm, thường theo công ty rồi theo đội. Tài liệu dùng dạng company.team trong hầu hết ví dụ. Với pipeline dữ liệu, đặt theo nguồn hoặc theo đội sở hữu sẽ giúp phân quyền và tìm kiếm về sau. Đổi namespace khi flow đã chạy lâu là việc phiền, nên nghĩ trước một chút.
Inputs
Trang Inputs nêu input có kiểu và được kiểm tra khi tạo execution. Thiếu input bắt buộc hoặc giá trị sai thì execution không được tạo. Mỗi input cần id và type, mặc định là bắt buộc, required false để cho phép bỏ qua. Trong flow dùng cú pháp inputs chấm tên.
Outputs
Trang Outputs nêu output lưu trong ngữ cảnh execution, task sau truy cập qua outputs chấm id task chấm thuộc tính. Tài liệu cảnh báo không dùng output để mang mật khẩu hay token, vì chúng lưu dạng rõ trong cơ sở dữ liệu, storage, log và phản hồi API. Với API có khóa, dùng secret.
Internal storage
Tài liệu nêu task sinh kết quả lớn sẽ ghi vào internal storage và trả về URI, task sau tham chiếu URI đó. Đây là mấu chốt của truy vết: tệp thô không chảy qua ngữ cảnh, chỉ có URI. Tệp có thể xem trước và tải về từ tab Input/Output của execution.
OutputValues
Tài liệu đưa ví dụ task OutputValues phát các giá trị có tên cho task sau, truy cập bằng outputs chấm id chấm values chấm khóa. Bài dùng task này để gom manifest của execution. Đây là cách đơn giản để có một chỗ duy nhất ghi URL nguồn và artifact.
- id: produce_output
type: io.kestra.plugin.core.output.OutputValues
values:
result: my output {{ execution.id }}
Khối trên chép từ tài liệu. Biểu thức execution.id cho mã của lần chạy hiện tại.
Task Download
Trang HTTP Download mô tả task tải tệp, với các output code, headers, length và uri. Uri là đường dẫn trong internal storage. Trang này có thuộc tính allowFailed, ví dụ để false. Trình mô phỏng coi mã lỗi HTTP là task hỏng, anh em đọc lại mô tả thuộc tính trên đúng phiên bản đang dùng.
Trạng thái execution
Trang Execution liệt kê các trạng thái như CREATED, RUNNING, SUCCESS, WARNING, FAILED, RETRYING, KILLED. Pipeline nên quan tâm ít nhất ba trạng thái cuối: SUCCESS, WARNING và FAILED. WARNING là chạy xong nhưng có cảnh báo, không nên coi như thành công thuần túy.
Errors, allowFailure và afterExecution
Trang Errors mô tả ba cơ chế. Khối errors chạy khi có task lỗi. allowFailure biến lỗi của một task thành cảnh báo và cho luồng đi tiếp. afterExecution chạy sau khi execution kết thúc. Ví dụ tài liệu dùng hàm tasksWithState để lấy task lỗi đầu tiên.
Retry
Trang Retries có ví dụ type constant, maxAttempts và interval theo định dạng ISO 8601, như PT15M. Tài liệu ghi rõ một task với maxAttempts 5 chạy tối đa 5 lần tổng cộng, gồm lần đầu và 4 lần thử lại. Bài dùng 3 lần, cách nhau 1 giây.
Triggers
Trang Triggers mô tả Schedule, sự kiện và webhook. Schedule dùng biểu thức cron. Với API đối tác, lịch theo giờ là đủ. Lab để disabled true vì không có máy chủ chạy lịch, flow chỉ được gọi tay trong trình mô phỏng.
Khai báo flow input, trigger và các task YAML của Kestra workflow tải API
Phần này là tệp flow.yml đầy đủ, chia từng đoạn.
Phần đầu và input
Flow có id, namespace, label và hai input. api_url có kiểu URI, page có kiểu INT.
id: fetch_catalog
namespace: lab.crawl
labels:
source: catalog-api
inputs:
- id: api_url
type: URI
defaults: http://127.0.0.1:9477/api/items
- id: page
type: INT
defaults: 1
Label giúp lọc execution theo nguồn trên giao diện. Địa chỉ 9477 là fixture của lab, thay bằng API thật khi triển khai.
Task tải
Task fetch tải về internal storage và thử lại ba lần với lỗi.
tasks:
- id: fetch
type: io.kestra.plugin.core.http.Download
uri: "{{ inputs.api_url }}?page={{ inputs.page }}"
retry:
type: constant
maxAttempts: 3
interval: PT1S
Không có code Python nào ở đây. Tải là việc của task có sẵn, kết quả là một URI.
Task xử lý
Task parse nhận tệp thô qua inputFiles, xuất ra items.jsonl qua outputFiles. Cả hai thuộc tính đều có trong trang Python Script của Kestra. Task này chạy trong môi trường có Python, thường là container.
- id: parse
type: io.kestra.plugin.scripts.python.Script
inputFiles:
raw.json: "{{ outputs.fetch.uri }}"
outputFiles:
- items.jsonl
script: |
import json
d = json.load(open("raw.json", encoding="utf-8"))
with open("items.jsonl", "w", encoding="utf-8") as f:
for x in d["items"]:
f.write(json.dumps({"id": x["id"], "price": x["price"]}) + "\n")
Đoạn Python viết thẳng trong flow là cách ngắn nhất để bắt đầu. Khi logic lớn lên, tách ra tệp riêng trong namespace.
Task manifest
Task cuối gom các giá trị để truy vết. Đây là thứ biến một lần chạy thành bản ghi có thể tra cứu.
- id: manifest
type: io.kestra.plugin.core.output.OutputValues
values:
execution_id: "{{ execution.id }}"
source_url: "{{ inputs.api_url }}?page={{ inputs.page }}"
raw_uri: "{{ outputs.fetch.uri }}"
http_code: "{{ outputs.fetch.code }}"
artifact: "{{ outputs.parse.outputFiles['items.jsonl'] }}"
Cú pháp outputFiles với dấu ngoặc vuông dùng cho tên tệp có dấu chấm.
Nhánh lỗi và lịch
Nhánh errors ghi log tên task lỗi, trigger đặt lịch mỗi giờ. Lab để disabled true.
errors:
- id: alert
type: io.kestra.plugin.core.log.Log
level: ERROR
message: "Task loi: {{ tasksWithState('FAILED')[0]['taskId'] }}"
triggers:
- id: hourly
type: io.kestra.plugin.core.trigger.Schedule
cron: "0 * * * *"
disabled: true
Thực tế, nhánh errors nên gửi cảnh báo tới kênh của nhóm thay vì chỉ ghi log. Biểu thức tasksWithState lấy theo ví dụ của tài liệu.
Khóa API để ở đâu
Fixture không cần khóa. API thật thì dùng secret, ví dụ biểu thức secret trong header của task. Đừng đưa khóa vào input hay output, vì tài liệu cảnh báo chúng lưu dạng rõ. Input cũng hiện trên giao diện execution, ai xem được execution là xem được giá trị.
Bản thử PyYAML đọc được gì
Lab đọc flow.yml và in ra cấu trúc. PyYAML chỉ xác nhận YAML hợp lệ về cú pháp, không xác nhận đúng lược đồ Kestra.
doc flow fetch_catalog ['fetch', 'parse', 'manifest'] errors ['alert'] trigger Schedule
Muốn kiểm tra lược đồ, phải dán vào editor của Kestra hoặc gọi API validate của máy chủ.
Giữ flow trong kho mã
Flow là tệp văn bản, nên đưa vào git như mã nguồn. Giao diện Kestra sửa được trực tiếp, tiện để thử nhưng dễ tạo ra bản khác với kho mã. Quy ước đơn giản nhất: bản chạy thật chỉ cập nhật từ kho mã. Khi có sự cố, xem lịch sử commit biết ngay ai đổi retry hay đổi URL.
Tách cấu hình khỏi flow
Địa chỉ API của môi trường thử và môi trường chạy khác nhau. Dùng defaults trong input cho môi trường thử, và trigger truyền input khác khi chạy thật, hoặc dùng biến của namespace. Đừng nhân đôi flow chỉ để đổi một địa chỉ, vì hai bản sẽ lệch nhau chỉ sau vài tuần.
Timeout của task tải
API treo sẽ giữ task mãi nếu không có giới hạn. Tài liệu có trang Task Timeout để đặt thời gian tối đa cho task. Với API thông thường, vài phút là đủ. Đặt timeout thấp hơn chu kỳ lịch, để lần chạy treo không chồng lên lần sau.
Lưu output fetch thành artifact cho task parse trong Kestra workflow tải API
Phần này chạy flow qua trình mô phỏng.
Trình mô phỏng làm gì
Script Python đọc flow.yml, kiểm tra input theo kiểu, thay các biểu thức, chạy ba task theo thứ tự. Mỗi execution có một mã ngẫu nhiên và một thư mục riêng. Task fetch gọi HTTP thật tới fixture. Task parse chạy đúng logic Python của flow.
Ca chạy đúng
Lab gọi với page bằng 2. Cả ba task SUCCESS, thư mục execution có ba tệp.
7d48440b6b SUCCESS [('fetch', 'SUCCESS', 1), ('parse', 'SUCCESS', 1), ('manifest', 'SUCCESS', 1)]
tep ['items.jsonl', 'manifest.json', 'raw.json']
Số cuối mỗi cặp là số lần thử. Mã 7d48440b6b do trình mô phỏng sinh, Kestra thật có mã dạng khác.
Manifest của execution

Manifest của execution
Manifest gom đủ thông tin để trả lời câu hỏi tệp này từ đâu.
{
"execution_id": "7d48440b6b",
"source_url": "http://127.0.0.1:9477/api/items?page=2",
"raw_uri": "kestra:///storage/7d48440b6b/raw.json",
"http_code": "200",
"artifact": "kestra:///storage/7d48440b6b/items.jsonl"
}
Đây là output thật của trình mô phỏng, đường dẫn kestra:/// là chuỗi giả theo dạng URI của Kestra.
Vì sao giữ cả tệp thô
Tệp thô là bằng chứng. Khi parser có lỗi, chạy lại từ tệp thô mà không phải gọi API. Khi đối tác nói dữ liệu sai, anh em cho xem chính xác API trả gì lúc đó. Xóa tệp thô để tiết kiệm đĩa là quyết định phải cân nhắc, nên giữ theo một thời hạn thay vì xóa ngay.
Dữ liệu đi qua URI, không qua biến
Tệp thô không nằm trong ngữ cảnh execution. Chỉ có URI đi qua biểu thức. Thiết kế này giữ ngữ cảnh gọn và tránh phình cơ sở dữ liệu. Đừng đọc cả phản hồi API rồi đưa vào OutputValues, vì tài liệu nói output lưu trong backend.
Input có kiểu chặn lỗi sớm
Lab gọi với page bằng chữ hai. Trình mô phỏng từ chối trước khi chạy task nào, không gọi API.
B page sai kieu {'id': None, 'state': 'REJECTED', 'why': 'input page khong phai INT'}
Theo tài liệu, input sai làm execution không được tạo. Thông báo thật khác, ý nghĩa giống: không phí một lượt gọi API đối tác vì một lỗi gõ nhầm.
Validator cho input
Tài liệu nêu kiểu STRING có validator bằng biểu thức chính quy, kiểu khác có ràng buộc riêng. Với API có hạn mức, thêm giới hạn cho page sẽ chặn thêm một lớp lỗi. Lab chỉ kiểm tra kiểu cơ bản.
Phân trang trong Kestra
Flow mẫu chỉ tải một trang, truyền page làm input. Tải nhiều trang có hai cách: một task script tự lặp, hoặc task lặp có sẵn của Kestra với subflow cho từng trang. Cách thứ hai có execution riêng mỗi trang, truy vết tốt hơn nhưng nặng hơn. Lab không thử, nên anh em cân nhắc theo số trang thật.
Chạy execution có input fixture và lỗi được kiểm soát với Kestra workflow tải API
Phần này là các ca lỗi.
Ca API lỗi rồi hồi phục
Fixture trả 503 hai lần, lần ba trả 200. Task fetch thử ba lần và qua được, flow đi tiếp bình thường.
SUCCESS [('fetch', 'RETRYING', 1), ('fetch', 'RETRYING', 2), ('fetch', 'SUCCESS', 3), ('parse', 'SUCCESS', 1), ('manifest', 'SUCCESS', 1)]
Trạng thái RETRYING lấy từ danh sách của tài liệu. Cách đếm lần thử trong trình mô phỏng theo mô tả maxAttempts là tổng số lần chạy.
Ca API lỗi liên tục
Fixture trả 503 mãi. Task thử đủ ba lần rồi FAILED, execution FAILED, nhánh errors chạy, thư mục execution không có tệp nào.
FAILED [('fetch', 'RETRYING', 1), ('fetch', 'RETRYING', 2), ('fetch', 'FAILED', 1)] alert: Task loi: fetch ('fetch', 'RuntimeError', 'HTTP 503 sau 3 lan') so goi 3 tep []
Fixture đếm đúng 3 lần gọi. Số 1 ở cặp cuối là cách ghi của trình mô phỏng, không nên hiểu là lần thứ nhất.
Ca dữ liệu thiếu trường

Lỗi xử lý, tệp thô còn nguyên
Fixture trả 200 với item không có price. Task fetch thành công, task parse lỗi KeyError, execution FAILED. Tệp raw.json còn đó để xem, items.jsonl dở dang.
FAILED [('fetch', 'SUCCESS', 1), ('parse', 'FAILED', 1)] alert: Task loi: parse ('parse', 'KeyError', "'price'") tep ['items.jsonl', 'raw.json']
Đây là lý do tách tải và xử lý. Lỗi xử lý không cần gọi lại API, vì tệp thô đã có.
Tệp dở dang
Dòng output trên có items.jsonl dù parse lỗi. Script ghi dần từng dòng, nên lỗi ở dòng giữa để lại tệp thiếu. Trên Kestra thật, outputFiles của task lỗi có được lưu hay không cần kiểm tra. Task sau phải chỉ đọc artifact của execution SUCCESS, đừng lấy tệp theo tên.
Kiểm tra hợp đồng dữ liệu sớm
Lỗi KeyError ở trên báo khá muộn và không nói được gì ngoài tên trường. Trước vòng lặp, script nên kiểm tra các trường bắt buộc rồi báo một thông báo rõ: API đổi hợp đồng, thiếu price ở dòng bao nhiêu. Người nhận cảnh báo lúc nửa đêm sẽ biết phải gọi ai, thay vì đi đọc stack trace.
need = {"id", "price"}
bad = [i for i, x in enumerate(d["items"]) if not need <= x.keys()]
if bad:
raise ValueError(f"Thieu truong o {len(bad)} item, dau tien o vi tri {bad[0]}")
Đoạn này là ví dụ thêm vào script parse, chưa chạy trong lab.
Ghi tệp đầu ra an toàn
Để tránh tệp dở dang, script ghi vào tệp tạm rồi đổi tên sau khi xong. Đổi tên là thao tác gọn, tệp items.jsonl chỉ xuất hiện khi đã đầy đủ. Với outputFiles của Kestra, điều này còn giúp task lỗi không để lại artifact gây hiểu lầm.
Thử lại đúng chỗ
Retry đặt ở task fetch, không đặt ở parse. Lỗi mạng và 5xx là tạm thời, thử lại có ích. Lỗi KeyError là lỗi logic hoặc lỗi hợp đồng dữ liệu, thử lại chỉ tốn thời gian. Với 4xx, thử lại cũng vô ích, trừ 429 phải chờ theo Retry-After.
Lỗi |
Task |
Cách xử lý |
|---|---|---|
Mạng, 5xx |
fetch |
Retry vài lần có giãn cách |
429 |
fetch |
Giảm tần suất, tôn trọng hạn mức |
401, 403 |
fetch |
Không thử lại, báo người |
404 |
fetch |
Tùy API, có thể là hết dữ liệu |
Sai cấu trúc JSON |
parse |
Không thử lại, giữ tệp thô |
Khi nào dùng allowFailure
allowFailure cho flow đi tiếp dù task lỗi, execution chuyển WARNING. Với một lô nhiều nguồn, một nguồn lỗi không nên chặn nguồn khác. Với flow một nguồn như lab, không nên dùng, vì task sau cần đầu vào của task trước.
Chạy lại một execution
Giao diện Kestra có các thao tác chạy lại execution hoặc từ một task. Trạng thái RESTARTED trong tài liệu liên quan tới chuyện đó. Lab không có phần này. Cần cẩn thận: chạy lại từ task parse dùng lại tệp thô cũ, chạy lại từ fetch thì gọi API lần nữa.
Trùng lịch chạy
Lượt chạy dài hơn chu kỳ lịch có thể chồng lên nhau. Tài liệu có khối Concurrency để giới hạn số execution song song của một flow. Với API có hạn mức, đặt giới hạn 1 là cách an toàn. Lab gọi tay nên không gặp chuyện này.
Truy lại execution ID tới input và artifact cuối của Kestra workflow tải API
Phần này là tài sản chính: đi ngược từ tệp về nguồn.
Bài kiểm tra truy vết
Lab lấy một artifact và cố trả lời ba câu: lần chạy nào, URL nào, tệp có đúng không. Tất cả lấy từ manifest và mã băm của tệp.
733a329c44 http://127.0.0.1:9477/api/items?page=3 4c7156836f61 2
Bốn giá trị là execution ID, URL nguồn, 12 ký tự đầu của SHA-256, và số dòng. Đủ để ghi vào sổ dữ liệu.
Đưa manifest ra ngoài Kestra
Execution của Kestra có thể bị dọn theo chính sách lưu trữ. Muốn truy vết dài hạn, ghi manifest vào kho của nhóm, một bảng hay một tệp JSON Lines đều được. Thêm mã băm của artifact và số bản ghi. Khi tệp đến tay bên khác, mã băm chứng minh nó chưa bị đổi.
{"execution_id": "733a329c44", "flow": "lab.crawl.fetch_catalog", "source_url": "http://127.0.0.1:9477/api/items?page=3", "sha256": "4c7156836f61", "rows": 2}
Dòng trên dùng số liệu thật của lab, mã băm đã rút ngắn.
Label theo nguồn và lượt
Label có thể đặt lúc chạy, giúp lọc execution trên giao diện. Thêm nhãn mã đối tác hoặc ngày dữ liệu, tra cứu sẽ nhanh hơn nhiều so với đọc log. Tài liệu có trang riêng về Labels, gồm cả cách lọc và nhóm flow.
Đọc log của task
Mỗi task có log riêng trong execution. Trình mô phỏng không có phần này, nên ProxyVN chỉ nêu từ tài liệu. Khi gỡ lỗi, in số bản ghi và mã trạng thái là đủ, không cần in cả dữ liệu.
Thời hạn giữ artifact
Internal storage không phải kho lưu trữ dài hạn. Có quy định giữ bao lâu, rồi đẩy artifact sang kho đối tượng của nhóm. Manifest lúc đó phải cập nhật đường dẫn mới. Đừng để giao diện Kestra là nơi duy nhất chứa bằng chứng.
Đối soát theo ngày
Mỗi ngày đếm số execution SUCCESS theo lịch so với số đáng lẽ phải có. Trigger lỡ một lần chạy thì không có execution FAILED nào để báo, chỉ có khoảng trống. Vì thế phải đếm kỳ vọng so với thực tế, thay vì chỉ cảnh báo khi lỗi.
Theo dõi kích thước và số bản ghi
Execution SUCCESS với 0 bản ghi có thể là sự cố. Đặt ngưỡng tối thiểu, thêm kiểm tra sau parse. Tài liệu có khối Checks để chặn input không đạt, còn kiểm tra đầu ra anh em tự thêm bằng một task. Dữ liệu tụt đột ngột cũng nên báo động.
Ai được xem execution
Execution chứa input, log và tệp. Nếu dữ liệu có thông tin khách hàng, quyền xem execution cũng là quyền xem dữ liệu. Phân quyền theo namespace là tính năng cần kiểm tra theo phiên bản anh em dùng. Log cũng phải sạch, đừng in cả phản hồi API ra log chỉ để gỡ lỗi rồi quên xóa.
Proxy trong flow này
API đối tác thường không cần proxy. Nếu gọi từ máy chủ cần đi ra qua IP tại Việt Nam, task HTTP của Kestra có cấu hình kết nối riêng, xem trang plugin theo đúng phiên bản. Với website được phép thu thập, có lúc cần IP tại Việt Nam để nhận đúng nội dung trong nước. Khi đó anh em có thể mua proxy tại trang chủ ProxyVN. Proxy không thay được retry và không tạo ra truy vết. Bối cảnh có ở bài Web Scraping proxy là gì, cách ghi chuỗi cấu hình ở bài định dạng proxy.
Không ghi thông tin proxy vào output
Mật khẩu proxy là bí mật, cùng nhóm với khóa API. Đưa vào secret, không đưa vào input hay output. Trong manifest chỉ ghi nhãn đường đi, ví dụ vn-static, nếu cần cho điều tra. Tài liệu đã cảnh báo output lưu dạng rõ, nên cẩn thận là đúng.
Đầu ra nghiệm thu của Kestra workflow tải API
Phần này gom tiêu chí và phần chưa thử.
Danh sách kiểm tra
Flow đạt khi mọi dòng dưới đây đúng.
- Input có kiểu, API URL không viết cứng trong task.
- Khóa API và mật khẩu proxy nằm trong secret.
- Tải và xử lý là hai task riêng.
- Retry chỉ đặt ở task tải.
- Có nhánh errors gửi cảnh báo thật.
- Có manifest chứa execution ID, URL nguồn, URI thô, artifact.
- Manifest được ghi ra ngoài Kestra kèm mã băm.
- Có đối soát số execution theo lịch.
Bảng kết quả lab

Bảng các ca chạy
Bảng này gom các ca đã chạy trên trình mô phỏng.
Ca |
Trạng thái |
Số lần gọi API |
Tệp còn lại |
|---|---|---|---|
Chạy đúng |
SUCCESS |
1 |
raw, items, manifest |
page sai kiểu |
Không tạo execution |
0 |
Không |
503 hai lần rồi 200 |
SUCCESS |
3 |
raw, items, manifest |
503 liên tục |
FAILED, chạy errors |
3 |
Không |
Thiếu trường price |
FAILED ở parse, chạy errors |
1 |
raw, items dở dang |
Khi nào không cần Kestra
Một script chạy mỗi ngày, ít bước, một người trông coi thì cron cộng log vẫn đủ. Kestra đáng dùng khi có nhiều flow, nhiều người cùng xem, cần truy vết theo lần chạy. Thêm một máy chủ phải vận hành là chi phí thật, nên cân nhắc theo số flow anh em sẽ có sau một năm.
Những gì lab chưa chạy
Chưa chạy Kestra thật. Flow chưa được kiểm tra lược đồ. Chưa chạy trigger, giao diện, internal storage thật, script task trong container, secret, label động, chạy lại execution, Concurrency, subflow. Các trạng thái và thứ tự chạy là mô phỏng theo tài liệu.
Thử trên Kestra thật
Thứ tự gợi ý: dán flow vào editor, sửa mọi lỗi lược đồ, đổi API URL sang fixture truy cập được từ máy chủ Kestra, chạy tay một lần. Xem tab Input/Output có đúng hai tệp và manifest không. Sau đó thử ba ca lỗi, rồi mới bật trigger.
Phiên bản plugin
Tài liệu hiện có nhiều phiên bản Kestra, trang đọc ngày 04/11/2026 hiển thị 2.0 là mới nhất. Tên type và thuộc tính có thể đổi qua các bản. Ghi phiên bản Kestra và plugin vào đầu tệp flow dưới dạng chú thích. Một năm sau, người đọc sẽ biết flow viết cho bản nào.
Kestra workflow tải API: câu hỏi thường gặp
Các câu dưới đây gom những điểm anh em hay hỏi.
Flow trong bài đã chạy trên Kestra thật chưa?
Chưa. Tệp YAML viết theo tài liệu, chạy qua trình mô phỏng tự viết. Anh em phải dán vào editor của Kestra để kiểm tra lược đồ.
Vì sao tách tải và xử lý?
Để lỗi xử lý không cần gọi lại API. Lab thấy khi thiếu trường price, tệp thô vẫn còn và có thể chạy lại phần parse.
Có nên đưa token API vào input không?
Không. Tài liệu cảnh báo output lưu dạng rõ, và input hiện trên giao diện execution. Dùng secret.
maxAttempts 3 là thử lại mấy lần?
Theo ví dụ tài liệu, maxAttempts tính cả lần đầu. Vậy 3 nghĩa là chạy tối đa 3 lần. Lab đếm đúng 3 lần gọi API.
Làm sao biết tệp đến từ lần chạy nào?
Dùng manifest chứa execution ID, URL nguồn và URI tệp, ghi ra kho riêng kèm mã băm. Lab truy được từ artifact về URL page=3.
Kestra khác Dagster ở đâu trong bài này?
Bài này khai báo flow bằng YAML với execution và artifact. Dagster xoay quanh asset viết bằng Python. Chọn công cụ tùy nhóm, bài không so sánh sâu.
Kestra workflow tải API và những điều cần nhớ
Kestra workflow tải API có giá trị khi mỗi execution truy được về input, URL nguồn và artifact cuối. Hãy tách tải với xử lý, đặt retry đúng chỗ, giữ khóa trong secret, ghi manifest ra ngoài. Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam khuyên anh em kiểm tra lược đồ Kestra workflow tải API trên máy chủ thật.