Bỏ qua, đến nội dung

API reference

Widget resource — uiWidgets

uiWidgets:findOne

Lấy widget theo UID.

GET /api/uiWidgets:findOne?filter[uid]=<widgetUid>

Response:

json
{
  "data": {
    "uid": "w1",
    "name": "dashboard-chart",
    "options": { "chartType": "bar", "dataSource": "orders" }
  }
}

uiWidgets:schema

Lấy schema đơn lẻ của widget (không bao gồm descendants).

GET /api/uiWidgets:schema?uid=<widgetUid>

uiWidgets:schemas

Lấy nhiều schema cùng lúc.

GET /api/uiWidgets:schemas?uids[]=w1&uids[]=w2

uiWidgets:schemaBundle

Lấy schema bundle — widget gốc kèm toàn bộ descendants tree.

GET /api/uiWidgets:schemaBundle?uid=<widgetUid>

Response chứa schema dạng nested JSON tree, bao gồm tất cả children ở mọi depth.

uiWidgets:save

Lưu widget (tạo mới nếu UID chưa tồn tại, cập nhật nếu đã có).

POST /api/uiWidgets:save
Body: {
  "uid": "w_new",
  "name": "my-chart",
  "options": { "chartType": "line" }
}

uiWidgets:duplicate

Nhân bản widget kèm toàn bộ descendants. Sinh UID mới cho tất cả node.

POST /api/uiWidgets:duplicate
Body: {
  "uid": "w1",
  "targetParentUid": "w_parent",
  "position": "afterEnd"
}
ParamMô tả
uidUID widget cần nhân bản
targetParentUidUID parent đích (nếu khác parent hiện tại)
positionVị trí: beforeBegin, afterBegin, beforeEnd, afterEnd

uiWidgets:attach

Gắn widget (đã tồn tại) vào parent tại vị trí chỉ định.

POST /api/uiWidgets:attach
Body: {
  "uid": "w_detached",
  "targetParentUid": "w_parent",
  "position": "beforeEnd"
}

uiWidgets:move

Di chuyển widget sang parent khác. Cập nhật toàn bộ closure paths.

POST /api/uiWidgets:move
Body: {
  "uid": "w3",
  "targetParentUid": "w_new_parent",
  "position": "afterBegin"
}

uiWidgets:destroy

Xóa widget kèm tất cả descendants.

DELETE /api/uiWidgets:destroy?uid=<widgetUid>

uiWidgets:mutate

Batch operations — thực hiện nhiều thay đổi trong một transaction.

POST /api/uiWidgets:mutate
Body: {
  "operations": [
    { "type": "save", "uid": "w1", "options": { "title": "Updated" } },
    { "type": "destroy", "uid": "w_old" },
    { "type": "move", "uid": "w3", "targetParentUid": "w1", "position": "afterEnd" }
  ]
}

Variables — variables

variables:resolve

Resolve danh sách biến template thành giá trị thực tế.

POST /api/variables:resolve
Body: {
  "variables": [
    "ctx.currentUser.id",
    "ctx.currentUser.nickname",
    "ctx.currentTime"
  ]
}

Response:

json
{
  "data": {
    "ctx.currentUser.id": 5,
    "ctx.currentUser.nickname": "Admin",
    "ctx.currentTime": "2025-06-15T10:30:00Z"
  }
}

Lưu ý: Cú pháp biến sử dụng dạng path string (VD: ctx.currentUser.id). Phía client dùng cú pháp mustache để nhúng biến vào template, nhưng server nhận path string qua API.


Query Service — queryService

queryService:run

Chạy query trực tiếp.

POST /api/queryService:run
Body: {
  "dataSourceKey": "main",
  "sql": "SELECT id, title FROM orders WHERE status = :status",
  "params": { "status": "pending" }
}

SQL được xử lý qua transformSQL (sanitize) và parseLiquidContext (resolve biến Liquid) trước khi thực thi.

queryService:runById

Chạy query đã lưu theo UID.

POST /api/queryService:runById
Body: {
  "uid": "q1",
  "params": { "status": "pending" }
}

queryService:save

Lưu query để tái sử dụng.

POST /api/queryService:save
Body: {
  "uid": "q_orders_pending",
  "dataSourceKey": "main",
  "sql": "SELECT id, title FROM orders WHERE status = :status"
}

queryService:getBind

Lấy data binding — ánh xạ giữa query result columns và widget fields.

GET /api/queryService:getBind?uid=<queryUid>

Response:

json
{
  "data": {
    "queryUid": "q1",
    "bindings": {
      "id": "rowKey",
      "title": "label",
      "amount": "value"
    }
  }
}

Ví dụ sử dụng

Tạo widget và gắn vào parent

typescript
await agent.resource('uiWidgets').save({
  values: {
    uid: 'w_chart_1',
    name: 'sales-chart',
    options: { chartType: 'bar', dataSourceKey: 'main' },
  },
});

await agent.resource('uiWidgets').attach({
  values: {
    uid: 'w_chart_1',
    targetParentUid: 'w_dashboard',
    position: 'beforeEnd',
  },
});

Resolve biến và chạy query

typescript
const vars = await agent.resource('variables').resolve({
  values: {
    variables: ['ctx.currentUser.id'],
  },
});

const userId = vars.body.data['ctx.currentUser.id'];

const data = await agent.resource('queryService').run({
  values: {
    dataSourceKey: 'main',
    sql: 'SELECT * FROM orders WHERE created_by_id = :userId',
    params: { userId },
  },
});