Hands-on Implementation: xây dựng một bản triển khai có thể vận hành
Cài đặt, kết nối Postgres, viết data model đầu tiên, gọi API, sau đó xây dựng một dashboard Angular và một ứng dụng low-code.
Mục lục chương
Chuẩn bị môi trường
Cài Cube CLI, tạo dự án, chạy Postgres và Cube bằng Docker Compose.
Handbook dùng Cube CLI để sinh khung dự án với driver Postgres, sau đó dùng Docker Compose khởi chạy Postgres và Cube ở chế độ nền. Đánh dấu từng bước sau khi hoàn thành; trình duyệt này lưu lại trạng thái đánh dấu.
npm install -g cubejs-cli
cubejs create ng-demo -d postgres cd ng-demo
docker-compose up -d
-d postgres trong lệnh tạo dự án chọn database driver. Cờ -d trong docker-compose up mang nghĩa khác: chạy ở chế độ nền (detached).Kết nối nguồn dữ liệu
Sáu biến môi trường cho kết nối, một biến cho bảo mật API.
Cube đọc thông tin kết nối từ file .env. Nguồn dữ liệu trong ví dụ là Postgres, chạy local hoặc trên cloud. Chọn từng dòng để xem chức năng của biến tương ứng. Biến cuối cùng, CUBEJS_API_SECRET, không phục vụ kết nối mà dùng để kiểm tra token của client. Các giá trị trong ví dụ là placeholder, cần thay bằng giá trị thực tế.
Sau khi kết nối, cần nạp dữ liệu mẫu. Handbook gợi ý hai bộ: bản dump thương mại điện tử ecom-dump.sql, hoặc bộ US Superstore 9.994 dòng. Data model ở mục sau dùng bảng orders theo cấu trúc Superstore.
Đọc sâuLệnh nạp dữ liệu và cấu trúc bảng orders
Nạp bản dump mẫu vào một database mới:
curl http://cube.dev/downloads/ecom-dump.sql > ecom-dump.sql createdb ecom psql --dbname ecom -f ecom-dump.sql
Bảng orders theo cấu trúc Superstore. Mỗi dòng là một sản phẩm trong đơn nên order_id có thể lặp lại; do đó primary key là row_num.
CREATE TABLE orders (
row_num INT PRIMARY KEY,
order_id TEXT,
order_date TIMESTAMP WITHOUT TIME ZONE,
ship_date TIMESTAMP WITHOUT TIME ZONE,
ship_mode TEXT,
customer_id TEXT,
customer_name TEXT,
segment TEXT,
country TEXT,
city TEXT,
state TEXT,
postal_code TEXT,
region TEXT,
product_id TEXT,
category TEXT,
sub_category TEXT,
product_name TEXT,
sales NUMERIC,
quantity NUMERIC,
discount NUMERIC,
profit NUMERIC
);Data model đầu tiên
Một file YAML cho bảng orders và một file JavaScript cho bảng users.
Từ v0.33, Cube chuẩn hóa ba quy ước: thư mục model tách thành model/cubes (các cube gốc) và model/views (data mart); tên theo snake_case cho cả YAML và JavaScript; dùng sql_table thay cho câu SELECT * dư thừa. Chọn từng dòng trong hai file dưới đây để xem giải thích.
Truy vấn qua Cube
Gửi JSON query tới REST API và nhận kết quả JSON với tên trường tương ứng.
REST API nhận truy vấn ở endpoint /cubejs-api/v1/load, kèm JWT trong header Authorization. Truy vấn liệt kê measures, dimensions và timeDimensions; mỗi trường trong kết quả giữ nguyên tên đã khai báo trong truy vấn. Chọn một dòng ở bên trái để làm nổi bật dòng tương ứng bên phải.
curl \
-H "Authorization: <JWT_TOKEN>" \
-H "Content-Type: application/json" \
-X POST \
-d '{"query": {"measures": ["orders.count", "orders.total_sales"], "dimensions": ["orders.city"]}}' \
http://localhost:4000/cubejs-api/v1/loadLệnh này truy vấn số đơn và tổng doanh số theo thành phố. Thay <JWT_TOKEN> bằng token được ký bằng CUBEJS_API_SECRET.
orders.order_date.month.Tích hợp vào ứng dụng frontend
Ví dụ dùng Angular: cấu hình client một lần, mỗi biểu đồ theo dõi một query.
Handbook đặt tên mục này theo Next.js nhưng ví dụ thực tế dùng Angular, với các thư viện @cubejs-client/core, @cubejs-client/ngx và ng2-charts. Module gốc cấu hình client một lần. Mỗi component biểu đồ đẩy query vào một Subject; client theo dõi Subject đó, gọi API và trả kết quả về. Sau đó chartPivot chuyển kết quả sang định dạng thư viện biểu đồ dùng được.
npm install -s ng2-charts @cubejs-client/core @cubejs-client/ngx moment
ng2-charts vẽ biểu đồ, @cubejs-client/core gọi API, @cubejs-client/ngx bọc client thành service của Angular.
Dashboard phân tích cơ bản
Năm ô, một component dùng lại, khác nhau ở chartType, query và title.
Dashboard gồm ba ô số đơn lẻ và hai biểu đồ theo thời gian. Tất cả các ô dùng chung component app-chart. Chọn từng ô để xem thẻ khai báo tương ứng.
Đọc sâuTemplate của chart component
Template xử lý hai trạng thái: khi chưa có dữ liệu thì hiển thị spinner; khi đã có dữ liệu thì vẽ canvas biểu đồ hoặc hiển thị một con số đơn lẻ.
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ title }}</h5>
<div class="card-text">
<div *ngIf="ready === false" class="d-flex justify-content-center text-dark">
<div class="spinner-border" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<canvas *ngIf="ready && showChart" baseChart height="300"
[datasets]="chartData" [labels]="chartLabels"
[options]="chartOptions" [chartType]="chartType"></canvas>
<h1 *ngIf="ready && !showChart" height="300">{{ chartData }}</h1>
</div>
</div>
</div>Template dùng showChart, chartLabels và chartOptions, nhưng đoạn chart.component.ts trong handbook không gán ba biến này. Khi triển khai thực tế cần bổ sung phần gán này, ví dụ đặt showChart theo chartType.
Kiểm tra kết quả truy vấn
Developer Playground hiển thị query, câu SQL được sinh ra, độ trễ và trạng thái cache.
Trước khi sử dụng số liệu trên dashboard, cần kiểm tra lại trong Developer Playground tại http://localhost:4000. Bốn bước dưới đây trình bày quy trình từ chọn trường đến đọc độ trễ.
Bài lab: Bubble.io gọi Cube REST API
Một ứng dụng low-code lấy số liệu theo phân khúc khách hàng qua REST.
Bubble.io dùng plug-in API Connector để gọi Cube. Truy vấn có một tham số động là segment, đổi theo dropdown trên màn hình. Thực hiện lần lượt các bước và đánh dấu sau khi hoàn thành.
Token và mật khẩu trong ví dụ đã thay bằng placeholder.