This repository contains an example REST server for the Apiary spreadsheet engine.
The REST server is written in TypeScript and based on hono. It keeps uploaded workbooks in memory for performance reasons, and persists the original .xlsx file and the model binary on disk. The workbook store will evict workbook models from memory when under pressure, but can load the model binary back into memory on demand.
POST /workbook— upload a new workbook (.xlsx file) using multi-part HTTP form uploadsPOST /workbook/:id— replace a workbook (.xlsx file) using multi-part HTTP form uploadsPOST /query/:id— run a query against a loaded workbookGET /workbooks— list the workbooks currently available in the serverGET /openapi— OpenAPI 3.0 spec (JSON)
The query is a JSON object:
{
"apply": {
"A1": 42,
"B2": "hello"
},
"read": ["C1", "D1:D10"]
}apply sets cell values before reading — this is useful for "what-if" scenarios. read is a list of A1-style cell or range references to return.
The response is keyed by expression. Single cells return a cell object with ref, ranges return a dict keyed by cell reference. Cell objects are based on JSF Cell — the t field indicates the value type: n (number), s (string), b (boolean), e (error), or z (empty).
{
"C1": { "t": "n", "v": 142, "ref": "C1" },
"D1:D3": {
"D1": { "t": "n", "v": 1 },
"D2": { "t": "s", "v": "hello" },
"D3": { "t": "n", "v": 42, "num_format": "#,##0", "formatted": "42" }
}
}The query does not persist changes between requests; it is not an editing endpoint.
{
"id": "uuid",
"filename": "Book1.xlsx",
"modified": "2025-03-05T16:38:00.000Z",
"status": "hot"
}The workbook status indicates whether it's currently in memory (hot) or only on disk (cold). A cold workbook will be loaded into memory on the first query, making that request slower. If the workbook failed to load it will be in an error state.
npm install
npm run devThe server listens on port 3000 by default. Configuration is via environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server port |
WORKBOOK_DIR |
./workbooks |
Directory for persisted workbook data |
MAX_HEAP_BYTES |
4294967296 (4 GiB) |
Heap threshold for LRU eviction |
# Upload a workbook
curl -F "[email protected]" http://localhost:3000/workbook
# List workbooks
curl http://localhost:3000/workbooks
# Query a cell
curl -X POST -H 'Content-Type: application/json' \
-d '{"read": ["A1"]}' \
http://localhost:3000/query/{id}