Skip to main content

File store

The file store persists data as JSON files in the .reqon-data directory.

Configuration​

store customers: file("customers")
store orders: file("orders")

Creates:

.reqon-data/
├── customers.json
└── orders.json

File structure​

Each store is a single JSON file containing an object keyed by record key:

{
"1": {"id": "1", "name": "Alice", "email": "alice@example.com"},
"2": {"id": "2", "name": "Bob", "email": "bob@example.com"}
}

The key is the value you pass in key:, falling back to record.id when you don't.

Use cases​

Local development​

mission DevSync {
store data: file("dev-data")

action Sync {
get "/items"
store response -> data { key: .id }
}
}

Persistent cache​

mission CachedSync {
store cache: file("sync-cache")

action IncrementalSync {
get "/items" { since: lastSync }
store response -> cache { key: .id, upsert: true }
}
}

Data export​

mission ExportData {
store export: file("export")

action Export {
get "/all-data"

for item in response.data {
map item -> ExportFormat {
// field mappings omitted
}
store item -> export { key: .id }
}
}
}

Data directory​

File stores write to .reqon-data/ by default. To change the directory, pass dataDir when running programmatically:

import { fromFile } from 'reqon-dsl';

await fromFile('mission.reqon', { dataDir: './my-data' });

The store name maps to a file inside that directory, so file("customers") becomes <dataDir>/customers.json.

Operations​

Write​

// Simple write
store response -> data { key: .id }

// Upsert (insert or update)
store response -> data { key: .id, upsert: true }

// Partial update (deep merge into the existing record, same as upsert)
store response -> data { key: .id, partial: true }

Read​

// Iterate all
for item in data { }

// Filter
for item in data where .status == "active" { }

Atomic writes​

File stores write atomically to prevent corruption:

  1. Write to a temporary file
  2. Rename it over the target file (atomic)

This keeps the file consistent even if the process is interrupted mid-write.

Best practices​

Use meaningful names​

// Good
store activeCustomers: file("active-customers")
store invoiceArchive: file("invoice-archive-2024")

// Avoid
store d: file("d")

Ignore the data directory in git​

The store creates a .gitignore inside .reqon-data/ that ignores its own *.json files, so checked-out data won't be committed by accident. You can also ignore the whole directory:

# Reqon local data
.reqon-data/

Use for development only​

The file store is for local development. For production storage, use the PostgREST store.

Regular backups​

For important development data:

# Backup before major changes
cp -r .reqon-data .reqon-data.backup

Size considerations​

The whole store is held in memory and rewritten on change, so it works best for modest datasets. For larger volumes, use the PostgREST store.

Debugging​

Inspect files​

# View raw data
cat .reqon-data/customers.json | jq

# Count records
cat .reqon-data/customers.json | jq 'length'

Reset data​

# Clear a specific store
rm .reqon-data/customers.json

# Clear all data
rm -rf .reqon-data/

Comparison​

AspectFile storeMemory store
PersistenceYesNo
SpeedFastFastest
ScalabilityMediumLimited
Use caseDevelopmentTesting