Bỏ qua để đến nội dung

JS action

Dùng JavaScript để điều phối nhiều action trong một lần chạy, trong sandbox có giới hạn, với whitelist action được gọi và kiểm tra chu trình khi publish.

4 phút đọc

JS action là action viết bằng JavaScript. JS action không kết nối tới DB nào. Nó gọi các action khác bằng executeAction(slug, params), ghép kết quả và trả về. Dùng JS action khi một thao tác gồm nhiều bước, ví dụ lấy dữ liệu từ hai action rồi ghép lại, hoặc chạy một chuỗi action ghi theo thứ tự.

  • Editor trở lên: tạo, sửa, publish JS action.
  • Admin: cho phép JS action gọi một action ở chế độ restricted (whitelist, xem bên dưới).
  1. Vào Xây dựng > Action, bấm Tạo action.
  2. Nhập Tên, Slug, chọn Loại là JavaScript (không cần chọn data source) và chọn Kiểu. Chọn Ghi dữ liệu nếu JS action gọi action ghi, để người chạy phải xác nhận.
  3. Bấm Tạo, sau đó viết code ở tab Định nghĩa. Gõ executeAction(" để editor gợi ý các action gọi được.
  4. Khai báo param của JS action ở phần Param như với action SQL. Code đọc các param này qua ctx.params.
  5. Bấm Lưu nháp, sau đó bấm Publish.

Code phải export default một hàm nhận ctx và trả về kết quả:

export default (ctx) => {
const orders = executeAction('orders-by-status', { status: ctx.params.status });
const customers = executeAction('list-customers');
const emailById = {};
customers.forEach((c) => {
emailById[c.id] = c.email;
});
return orders.map((o) => ({
id: o.id,
total: o.total,
customer_email: emailById[o.customer_id] || null,
}));
};
  • ctx gồm currentUser (id, email của người đang chạy), environment (id, slug, isProduction), params (param của JS action) và vars (biến của môi trường).
  • executeAction(slug, params) trả về mảng các dòng của action được gọi. Nếu action con lỗi, executeAction ném lỗi; bắt lỗi bằng try/catch.
  • Nếu hàm trả về mảng object, trang Chạy action hiển thị bảng. Nếu trả về một giá trị đơn, trang hiển thị một dòng.
  • Hai lời gọi tới cùng một action với cùng param trong một lần chạy chỉ thực thi một lần và dùng chung kết quả.

JS action chạy trong sandbox QuickJS phía server:

  • Không có fetch, require, hệ thống file hay mạng. executeAction là cách duy nhất để truy cập dữ liệu bên ngoài.
  • Tối đa 50 lời gọi executeAction mỗi lần chạy.
  • JS action gọi JS action lồng nhau tối đa 3 tầng.
  • Mỗi lần chạy tối đa 30 giây và 128 MB bộ nhớ.
  • Mỗi action con tự commit. Không có transaction chung cho cả chuỗi: nếu một bước sau lỗi, dữ liệu các bước trước đã ghi vẫn giữ nguyên. Dùng try/catch để gọi action bù trừ khi cần.
  • JS action chưa chạy nền được: không đưa vào hàng đợi, không chạy hàng loạt và không đặt lịch được.

Mỗi lời gọi executeAction đi qua toàn bộ bước kiểm tra quyền của action con, với quyền của người đang chạy JS action. Publish một JS action không cấp thêm quyền cho ai: nếu người chạy không có quyền chạy action con, lời gọi đó bị từ chối.

Whitelist: cho JS action gọi một action restricted

Phần tiêu đề “Whitelist: cho JS action gọi một action restricted”

Cách cấu hình thường dùng là để action con ở chế độ restricted và chỉ cho JS action gọi nó. Khi đó người dùng chỉ dùng được action con thông qua JS action.

  1. Mở action con, tab Cài đặt & quyền, thẻ Quyền trên action (cần vai trò Admin).
  2. Chuyển Chế độ quyền sang restricted — chỉ ai được cấp và xác nhận.
  3. Ở Cấp quyền chạy cho, chọn loại JS action, chọn JS action ở Chọn JS action…, sau đó bấm Cấp quyền.

Thẻ Quyền trên action ở chế độ restricted, danh sách cấp quyền có một JS actionThẻ Quyền trên action ở chế độ restricted, danh sách cấp quyền có một JS action

Quyền cấp cho JS action chỉ có tác dụng khi action con ở chế độ restricted. Khi đó, JS action gọi được action con bằng quyền của người chạy JS action, còn người dùng không thấy action con ở trang Chạy action nếu không được cấp quyền riêng.

Editor vẫn thấy mọi action trong phần gợi ý của editor, kể cả action restricted. Action xuất hiện trong gợi ý chưa chắc gọi được: lời gọi chỉ thành công khi admin đã thêm JS action vào danh sách cấp quyền của action đó.

  • Slug trong executeAction phải là chuỗi cố định, ví dụ executeAction('list-customers'). Slug ghép lúc chạy (executeAction(name)) bị từ chối, vì bước publish dựng đồ thị phụ thuộc từ chính đoạn code.
  • Mọi action được gọi phải tồn tại trong project.
  • Không được có chu trình: nếu A gọi B và B gọi lại A (trực tiếp hoặc gián tiếp), publish bị từ chối và trang hiện đường đi, ví dụ a → b → a.

Sau khi publish, action được JS action gọi không xoá được cho tới khi lời gọi đó được gỡ khỏi JS action.