LavaQL's query language lets you run analytics queries against any data source. You can use LavaQL through the playground, directly in code editors via the LSP, embedded as a web component in your own tools, or via the REST API to power backends and apps.
flowchart TB
A["CodeMirror\n(Autocomplete · Syntax highlight)"]
B["LSP over WebSocket\n(tower-lsp)"]
C["Parser\nLexer → AST (logos)"]
D["Introspector\nPostgres · GraphQL · OpenAPI → SQLite cache"]
E["SQLite\nSchema cache"]
F["REST API\n/sources · /eval"]
A --> B
B --> C
B --> E
F --> D
F --> E
D --> E
| Path | Description |
|---|---|
src/api/ |
HTTP handlers — sources.rs, schema.rs, eval.rs |
src/introspect/pgsql/ |
Postgres introspection pipeline → SQLite cache |
src/introspect/pgsql/sql/ |
Raw SQL files embedded at compile time via include_str! |
src/introspect/graphql/ |
GraphQL endpoint introspection pipeline → SQLite cache |
src/introspect/openapi/ |
OpenAPI 3.0 spec introspection pipeline → SQLite cache |
src/lsp/ |
LSP server over WebSocket — completions, hover, diagnostics |
src/parser/ |
Lexer (logos) + hand-written recursive-descent parser → AST |
src/eval/ |
Query execution |
playground/ |
Lit + CodeMirror 6 web component |
| Method | Endpoint | Description |
|---|---|---|
GET |
/sources |
All sources with their full cached schema |
POST |
/sources |
Introspect a Postgres, GraphQL, or OpenAPI source |
POST |
/eval |
Execute a LavaQL query |
GET |
/lsp |
LSP over WebSocket |
GET /sources returns each source with tables, columns, foreign_keys, indexes, enums, and relationships arrays inlined.
FROM and SHOW are required. All other clauses are optional.
FROM <dimension>
SHOW <metric | field>, …
[WHERE <field> <op> <value>]
[SINCE <offset | date>]
[UNTIL <offset | date>]
[GROUP BY <field>, …]
[HAVING <metric> <op> <value>]
[ORDER BY <field> ASC | DESC]
[LIMIT <n>]
<dimension> resolves against the DDS catalog (PascalCase, auto-generated from the introspected source). <metric> and <field> are catalog names, never raw column names.
Relative time offsets use -{n}{unit} — e.g. -7D, -1M, -3Q. Supported units: s m h D W M Q Y.
Operators: = != > >= < <= IN (…) NOT IN (…) LIKE.
cargo runcd playground && npm install && npm run devSet SQLITE_URL to override the database path (default: sqlite:lavaql.db).
curl -X POST http://localhost:1234/sources \
-H 'Content-Type: application/json' \
-d '{"name": "demo", "connection_string": "postgres://lavaql:lavaql@localhost:5432/demo"}'source_type can be "postgres" or "graphql". The connection_string is the GraphQL endpoint URL.
Countries API — tiny schema (Country, Continent, Language), good for a quick smoke-test:
curl -X POST http://localhost:1234/sources \
-H 'Content-Type: application/json' \
-d '{
"name": "countries",
"source_type": "graphql",
"connection_string": "https://countries.trevorblades.com/graphql"
}'Rick and Morty API — larger schema (Character, Episode, Location, …):
curl -X POST http://localhost:1234/sources \
-H 'Content-Type: application/json' \
-d '{
"name": "rickandmorty",
"source_type": "graphql",
"connection_string": "https://rickandmortyapi.com/graphql"
}'Both are public and require no authentication.
source_type: "openapi" accepts a URL to a JSON or YAML OpenAPI 3.0 spec. Stores operations, parameters, request bodies, and 200 responses (with body only).
curl -X POST http://localhost:1234/sources \
-H 'Content-Type: application/json' \
-d '{
"name": "baremetrics",
"source_type": "openapi",
"connection_string": "https://raw.githubusercontent.com/konfig-sdks/openapi-examples/refs/heads/main/baremetrics/openapi.yaml"
}'curl -X POST http://localhost:1234/sources \
-H 'Content-Type: application/json' \
-d '{
"name": "stripe",
"source_type": "openapi",
"connection_string": "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json"
}'curl http://localhost:1234/sourcescurl -X POST http://localhost:1234/eval \
-H 'Content-Type: application/json' \
-d '{"query": "FROM Orders SHOW revenue, order_count"}'