You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Point sqlize at an OpenAPI spec and query any REST API using SQL. Path parameters become `WHERE` clauses, query parameters become filters, response fields become columns. One tool, any API.
5
+
Query GitHub issues, Stripe customers, GitLab pipelines — any REST API that has an OpenAPI spec — using plain SQL. Pagination, auth, filter pushdown, and cross-API JOINs are handled automatically.
WHERE owner ='rust-lang'AND repo ='rust'AND state ='open'
13
+
LIMIT5;
14
14
```
15
15
16
-
```sql
17
-
sqlize>SELECTnumber, title, state FROM issues
18
-
>WHERE owner ='rust-lang'AND repo ='rust'AND state ='open'
19
-
>LIMIT5;
16
+
```
20
17
[5]{number,title,state}:
21
18
154162,"(EXPERIMENT) Replace zero-deps nodes with a singleton",open
22
19
154161,On E0277 tweak help when single type impls traits,open
@@ -25,25 +22,13 @@ sqlize> SELECT number, title, state FROM issues
25
22
154157,Enforce deterministic signed zero behavior in float min/max and clamp,open
26
23
```
27
24
28
-
Same tool, different API — Stripe:
29
-
30
-
```sh
31
-
export SQLIZE_BEARER_ENV_VAR=STRIPE_TEST_API_KEY
32
-
sqlize --spec specs/stripe-minimal.json
33
-
```
25
+
## Why SQL
34
26
35
-
```sql
36
-
sqlize>SELECT email, name FROM customers;
37
-
╭──────────────────────┬────────────────╮
38
-
│ email │ name │
39
-
├──────────────────────┼────────────────┤
40
-
│ sp@summerproject.com │ Summer Project │
41
-
╰──────────────────────┴────────────────╯
42
-
```
27
+
REST APIs are imperative — you need to know the endpoint, the parameters, the pagination scheme, the response shape. SQL is declarative — you say what you want and the engine figures out how to get it.
43
28
44
-
Powered by [Apache DataFusion](https://datafusion.apache.org/). Supports `SELECT`, `WHERE`, `ORDER BY`, `LIMIT`, `OFFSET`, `GROUP BY`, `HAVING`, `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `JOIN`, subqueries, CTEs, `UNION`/`INTERSECT`, `CASE`, `CAST`, and more. Read-only — no INSERT/UPDATE/DELETE.
29
+
The mapping is natural: endpoints become tables, parameters become columns, and the query planner translates SQL into API calls. `WHERE owner = 'rust-lang'` becomes a path parameter in the URL. `WHERE state = 'open'` becomes `?state=open` in the query string. `ORDER BY`, `GROUP BY`, `LIMIT` are applied locally by the engine after fetching.
45
30
46
-
Results are returned in [TOON](https://github.com/toon-format/toon) (compact, token-oriented encoding, 40-50% smaller than JSON), JSON, or as a table.
31
+
Powered by [Apache DataFusion](https://datafusion.apache.org/). Supports `SELECT`, `WHERE`, `ORDER BY`, `LIMIT`, `OFFSET`, `GROUP BY`, `HAVING`, `COUNT`, `SUM`, `AVG`, `MIN`, `MAX`, `JOIN`, subqueries, CTEs, `UNION`/`INTERSECT`, `CASE`, `CAST`, and more. Read-only.
sqlize>SELECTnumber, title FROM issues WHERE owner ='rust-lang'AND repo ='rust'LIMIT5;
87
58
```
88
59
89
-
Output is JSON by default, `--format toon` for compact output.
90
-
91
-
### Interactive REPL
60
+
### Query Stripe
92
61
93
62
```sh
94
-
sqlize --spec specs/github-minimal.json
63
+
export STRIPE_API_KEY=sk_test_...
64
+
export SQLIZE_BEARER_ENV_VAR=STRIPE_API_KEY
65
+
sqlize --spec specs/stripe-minimal.json
95
66
```
96
67
68
+
```sql
69
+
sqlize>SELECT email, name FROM customers;
97
70
```
98
-
sqlize> SHOW TABLES
99
-
sqlize> DESCRIBE issues
100
-
sqlize> SELECT number, title FROM issues WHERE owner = 'rust-lang' AND repo = 'rust' LIMIT 5;
101
-
```
102
-
103
-
Tab completion, SQL syntax highlighting, multiline input, persistent history.
104
71
105
-
With full OpenAPI specs, use `--tags` to filter endpoints by their OpenAPI [tag](https://swagger.io/docs/specification/v3_0/grouping-operations-with-tags/):
Output is JSON by default, `--format toon` for compact output, `--format table` for human-readable tables.
157
+
198
158
## How queries map to API calls
199
159
200
160
```sql
201
-
sqlize>EXPLAIN SELECTnumber, title FROM issues
202
-
>WHERE owner ='openclaw'AND repo ='openclaw'AND state ='open'
203
-
>ORDER BY created_at DESC
204
-
>LIMIT10;
161
+
EXPLAIN SELECTnumber, title FROM issues
162
+
WHERE owner ='openclaw'AND repo ='openclaw'AND state ='open'
163
+
ORDER BY created_at DESC
164
+
LIMIT10;
205
165
```
206
166
207
-
`WHERE` conditions on path parameters (`owner`, `repo`) are substituted into the URL. Query parameters (`state`) are pushed to the API as `?key=value`. Everything else (`ORDER BY`, `LIMIT`, `GROUP BY`, `JOIN`) is applied locally by DataFusion after the fetch.
167
+
-`owner`, `repo` — path parameters, substituted into the URL
168
+
-`state` — query parameter, pushed to the API as `?state=open`
169
+
-`ORDER BY`, `LIMIT` — applied locally by DataFusion after the fetch
208
170
209
171
Path parameters are required — omitting them fails at query planning, before any HTTP call is made.
210
172
211
173
## Pagination
212
174
213
-
sqlize paginates automatically using the standard `Link` header (`rel="next"`) or common response body fields (`next`, `next_url`). This works with GitHub, GitLab, Stripe, and most REST APIs without configuration.
175
+
sqlize paginates automatically using the standard `Link` header (`rel="next"`) or common response body fields (`next`, `next_url`). Works with GitHub, GitLab, Stripe, and most REST APIs without configuration.
214
176
215
177
Each table scan fetches pages lazily until one of these limits is reached:
216
178
217
-
-**SQL `LIMIT`** — when DataFusion can push it down (simple queries), only the needed pages are fetched
218
-
-**`max_rows`** (default 1000) — caps total rows per table scan when no SQL `LIMIT` applies (e.g. JOINs, aggregations, or queries without `LIMIT`)
219
-
220
-
The current page always completes, so actual row count may slightly exceed the cap.
179
+
-**SQL `LIMIT`** — only the needed pages are fetched
180
+
-**`max_rows`** (default 1000) — caps total rows per table scan when no SQL `LIMIT` applies
221
181
222
182
Override the default:
223
183
224
184
```sh
225
-
# CLI flag (one-off)
226
185
sqlize --spec specs/github.json --max-rows 5000
227
-
228
-
# Environment variable (persistent)
186
+
# or
229
187
export SQLIZE_MAX_ROWS=5000
230
188
```
231
189
232
-
## Why SQL
190
+
## Bring your own API
191
+
192
+
sqlize works with any REST API that has an OpenAPI 3.x spec. For large specs, use `--tags` to filter endpoints:
233
193
234
-
REST APIs are imperative — you need to know the endpoint, the parameters, the pagination scheme, the response shape. SQL is declarative — you say what you want and the engine figures out how to get it. The mapping is natural: endpoints become tables, parameters become columns, and the query planner translates SQL into API calls.
0 commit comments