DFQL Overview
DataFn Query Language - a JSON-based query and mutation language.
DFQL (DataFn Query Language) is a structured, JSON-based language for querying and mutating data. Every operation -- whether reading a single record, filtering a large dataset, or executing a multi-step transaction -- is expressed as a plain JSON object with well-defined fields.
Design Principles
DFQL is designed around three core principles:
- Uniform envelope pattern. Queries, mutations, and transactions all share a common shape: a
resourceandversionto identify the target, plus operation-specific fields. - Isomorphic execution. The same DFQL objects are used by both the client and server. A query written for the client executes identically on the server, enabling offline-first architectures with no translation layer.
- Composable operations. Filters, sorting, pagination, select projections, and aggregations can be combined freely within a single query.
Operation Types
DFQL supports three top-level operation types:
Queries
Retrieve data from a resource. Queries support filtering, sorting, pagination, field selection, aggregation, and full-text search.
const query: DfqlQuery = {
resource: "todos",
version: 1,
filters: { completed: false },
sort: ["priority:desc"],
limit: 20,
};Mutations
Create, update, or delete records. Mutations support core operations (insert, merge, replace, delete), capability operations (trash, restore, archive, unarchive, share, unshare), relation management, conditional guards, and debounced writes.
const mutation: DfqlMutation = {
resource: "todos",
version: 1,
operation: "insert",
record: { title: "Buy groceries", completed: false },
};Transactions
Execute a sequence of queries and mutations as an atomic unit. If any step fails, all preceding mutations are rolled back.
const transaction: DfqlTransact = {
atomic: true,
steps: [
{ mutation: { resource: "accounts", version: 1, operation: "merge", id: "acc_1", record: { balance: 900 } } },
{ mutation: { resource: "accounts", version: 1, operation: "merge", id: "acc_2", record: { balance: 1100 } } },
],
};Type Definitions
All DFQL types are exported from @datafn/core:
import type {
DfqlQuery,
DfqlMutation,
DfqlTransact,
DfqlSort,
DfqlCursor,
} from "@datafn/core";The DfqlQueryFragment and DfqlMutationFragment types omit the resource and version fields, which are useful when working through client table handles that inject those fields automatically.
Capability semantics are schema-driven. See Capabilities.
Normalization and Caching
DFQL objects can be normalized to a canonical form for use as cache keys:
import { normalizeDfql, dfqlKey } from "@datafn/core";
// Canonical JSON representation (sorted keys, stripped undefined)
const normalized = normalizeDfql(query);
// Stable string key for caching
const key = dfqlKey(query);normalizeDfql recursively sorts object keys alphabetically, strips undefined values, and preserves null. dfqlKey produces a deterministic JSON string from the normalized form.