SQLBraid: Viết SQL trực tiếp trong TypeScript, không cần lớp DSL query-builder

Công nghệ21 tháng 9, 2026·5 phút đọc

SQLBraid là bộ công cụ truy cập dữ liệu theo hướng SQL-first dành cho TypeScript, cho phép lập trình viên viết SQL thuần mà vẫn giữ được an toàn kiểu dữ liệu và ràng buộc tham số. Dự án vừa đạt phiên bản 1.0.0 với API công khai ổn định, hỗ trợ nhiều cơ sở dữ liệu như PostgreSQL, MySQL, SQLite, Oracle và SQL Server.

SQLBraid: Viết SQL trực tiếp trong TypeScript, không cần lớp DSL query-builder

Trong nhiều năm, các lập trình viên TypeScript thường phải lựa chọn giữa hai thái cực: hoặc viết SQL thuần nhưng thiếu an toàn kiểu, hoặc dùng query-builder/ORM để có kiểu dữ liệu nhưng phải học một DSL mới và đánh đổi bằng lớp dịch trung gian phức tạp. SQLBraid xuất hiện như một hướng đi thứ ba: giữ nguyên câu SQL trong tầm mắt, nhưng bổ sung ràng buộc giá trị an toàn, SQL động dễ đọc và hợp đồng kết quả tường minh.

Dự án vừa đạt mốc phiên bản 1.0.0 với API công khai ổn định, hiện được phát hành trên GitHub.

SQLBraid giải quyết vấn đề gì?

Điểm khác biệt cốt lõi của SQLBraid nằm ở chỗ nó không dịch SQL sang một ngôn ngữ trung gian. Thay vào đó, công cụ giữ câu SQL gần như nguyên bản, chỉ thêm các lớp bảo vệ cần thiết:

  • Nội suy ${value} luôn là ràng buộc giá trị — không bao giờ trở thành SQL thực thi, nhờ đó giảm thiểu rủi ro SQL injection.
  • SQL có cấu trúc sử dụng các helper tường minh như sql.ident, sql.fragment, sql.list, sql.join, sql.rawsql.empty.
  • Chỉ thị @braid như if, choose, when, otherwise, where, set, trim được trình biên dịch xử lý, các nhánh không hoạt động vẫn ở trạng thái "lazy".

Điều này có nghĩa là lập trình viên vẫn đọc được câu SQL quen thuộc, nhưng trình biên dịch đảm bảo mọi tham số được ràng buộc đúng cách.

Ví dụ khởi động nhanh

Trên Node.js 22.18 trở lên, đoạn mã sau tạo và đóng cơ sở dữ liệu trong bộ nhớ:

import { createNodeSqliteDatabase, sql } from "sqlbraid/node-sqlite";
import { DatabaseSync } from "node:sqlite";

const native = new DatabaseSync(":memory:");
native.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)");

const db = createNodeSqliteDatabase(native);
const userId = 1;
const users = await db.all(sql.rows`
  SELECT id, name FROM users WHERE id = ${userId}
`);

Người dùng cài đặt facade sqlbraid không có phạm vi, sau đó import một subpath kết hợp driver và dialect/query, chẳng hạn sqlbraid/pg, sqlbraid/mysql2, sqlbraid/node-sqlite hay sqlbraid/d1.

Hợp đồng kết quả và ánh xạ dữ liệu

SQLBraid phân biệt rõ ràng các loại truy vấn qua các thẻ khác nhau:

  • sql.rows — truy vấn trả về nhiều dòng
  • sql.command — lệnh UPDATE/INSERT/DELETE
  • sql.call — gọi stored procedure
  • sql — SQL đặc thù driver với loại kết quả chưa xác định

Các phương thức như db.all, db.one, db.maybeOnedb.stream yêu cầu sql.rows. Điều đáng chú ý là SQLBraid không tự động hydrate quan hệ, không duy trì identity map, cũng không suy luận kiểu kết quả SELECT/JOIN tùy ý. Ánh xạ là một dòng sang một giá trị ứng dụng — đơn giản và tường minh.

Người dùng có thể gắn Standard Schema vào truy vấn để kiểm tra kiểu dữ liệu:

const event = await db.one(eventQuery, { schema: EventSchema });

Hỗ trợ đa cơ sở dữ liệu

SQLBraid tách biệt ba trục độc lập: dialect (bề mặt SQL, quoting), driver (cầu nối giao thức, ràng buộc tham số) và runtime (Node, Bun, Deno, browser, Worker).

Các dialect chính thức bao gồm PostgreSQL, MySQL, MariaDB, SQLite, Oracle và SQL Server. Subpath driver hỗ trợ: pg, mysql2, node:sqlite, better-sqlite3, libsql, sqlite-wasm, d1, oracledbtedious.

SQLBraid không cài đặt driver cơ sở dữ liệu kèm theo — người dùng cần cài driver riêng.

Những gì SQLBraid cố tình không làm

Nhóm phát triển khá thẳng thắn về giới hạn của công cụ:

  • Không phải ORM
  • Không phải ngôn ngữ ưu tiên query-builder
  • Không phải trình phân tích SQL hoàn chỉnh
  • Không phải trình biên dịch SQL phổ quát
  • Không tự động mô phỏng cursor, transaction, cancellation hay các kênh routine bị thiếu

Thay vào đó, khi một tính năng không được hỗ trợ, SQLBraid báo lỗi tường minh thay vì âm thầm giả lập. Đây là triết lý thiết kế đáng chú ý: thà thất bại rõ ràng còn hơn che giấu sự khác biệt giữa các cơ sở dữ liệu.

Hệ sinh thái package

SQLBraid được chia thành nhiều package chuyên biệt:

  • sqlbraid — facade runtime chính
  • @sqlbraid/core — hợp đồng công khai, SPI ràng buộc
  • @sqlbraid/runtime — thực thi, session, lease, transaction
  • @sqlbraid/postgres, @sqlbraid/mysql, @sqlbraid/sqlite... — dialect và TypePolicy
  • @sqlbraid/opentelemetry — span DB client tùy chọn
  • @sqlbraid/cli, @sqlbraid/language-server — công cụ phát triển

Các package runtime không kéo theo dependency về tooling, metadata, codegen hay Vite.

Ý nghĩa cho lập trình viên Việt Nam

Với các đội ngũ phát triển tại Việt Nam đang làm việc với TypeScript và cơ sở dữ liệu quan hệ, SQLBraid là một lựa chọn đáng cân nhắc. Nhiều dự án hiện đại đang chuyển từ ORM nặng sang hướng tiếp cận nhẹ nhàng hơn, giữ SQL gần với cơ sở dữ liệu để dễ tối ưu hiệu năng.

Tuy nhiên, cần lưu ý rằng SQLBraid vẫn yêu cầu lập trình viên hiểu SQL thực sự — đây không phải công cụ dành cho người muốn tránh viết SQL. Với những ai đã quen SQL và chỉ cần an toàn kiểu cùng ràng buộc tham số, công cụ này có thể là giải pháp thay thế hợp lý cho các ORM cồng kềnh.

Dự án yêu cầu Node.js 22.18 trở lên và pnpm để phát triển. Bạn có thể tìm hiểu thêm tại repository GitHub chính thức.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗