The recommended way to add custom queries and mutations is through the CLI's create-endpoint command. It generates all necessary files (schema, config, types, JSON Schema) from a simple endpoint definition — the same way the pull command works, but from a JSON definition instead of an existing Trino table.
Creating an endpoint definition #
Define your endpoint as a JSON file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"version": "1.0",
"tableName": "user_events",
"catalog": "hive",
"schema": "analytics",
"fields": [
{ "name": "event_id", "type": "String", "options": { "required": true } },
{ "name": "message", "type": "String" },
{ "name": "timestamp", "type": "DateTime" }
],
"mutation": {
"loadStrategy": "full_load",
"type": "minio",
"bucket": "my-datalake",
"basePath": "analytics/user_events",
"endpoint": "http://localhost:9000"
}
}
Generating the endpoint #
Run the CLI to generate all files:
npx lakeql-cli create-endpoint --from-file ./my-endpoint.jsonThis generates:
1
2
3
4
5
6
7
src/schemas/custom/hive/analytics/user_events/
├── config.ts # Hive + storage config
├── endpoint.json # Persisted definition
├── json-schema.json # JSON Schema for Parquet serialization
├── query-schema.ts # GraphQL query with sorting, filtering, paging
└── mutation-schema.ts # GraphQL mutation with write pipeline
The config-registry.ts is updated automatically to include the new endpoint.
Query-only endpoints #
Omit the mutation field to generate a query-only endpoint:
1
2
3
4
5
6
7
8
9
10
11
12
{
"version": "1.0",
"tableName": "reports",
"catalog": "hive",
"schema": "analytics",
"fields": [
{ "name": "report_id", "type": "String" },
{ "name": "title", "type": "String" },
{ "name": "created_at", "type": "DateTime" }
]
}
Or explicitly disable mutations:
1
2
{ "mutation": false }
Field options #
Each field supports options for mutation input behavior:
| Option | Default | Description |
|---|---|---|
required | false | Field is required in mutation input |
readOnly | false | Field appears in queries but is excluded from mutation input |
validations | [] | Zod validation refinements (email, url, uuid, min, max, regex) |
1
2
3
4
5
6
7
8
9
{
"name": "email",
"type": "String",
"options": {
"required": true,
"validations": [{ "type": "email" }]
}
}
Mutation load strategies #
The mutation config supports three strategies. See Load Strategies for details.
| Strategy | Behavior |
|---|---|
full_load | Replace all data on every write |
full_load_append | Replace latest + keep history |
append | Append only |
File discovery #
The API server automatically discovers all schema files at startup by scanning for:
1
2
3
schemas/**/query-schema.{ts,js,mjs}
schemas/**/mutation-schema.{ts,js,mjs}
No manual registration is needed — just generate and start the server.