Fake / mock backend
Run a real local HTTP API with sample records, validation and CRUD operations.
A local API for learning
This memory-only customer service demonstrates real GET, POST, PATCH and DELETE requests. It is separate from the browser demo store. Restarting restores the initial records. It has no authentication or database and binds only to 127.0.0.1.
Start the server
Use Node.js 24.14+ for this optional local teaching server. The template itself does not require Node to host. From this documentation folder:
node examples/mock-server.cjsNo npm install is needed. Open http://127.0.0.1:5188/client for the included working HTML client. Keep the terminal open; Ctrl+C stops the server. If the port is occupied, use PowerShell:
$env:PORT = "5189"
node examples/mock-server.cjsChange the client URL and API base to that port. The browser client at /client uses the same origin automatically.
Try the full workflow
- Create a customer with a unique email.
- Search by name or email and edit the customer’s plan or status.
- Try a duplicate email: the server returns 409 and the form keeps your entries.
- Click Simulate load failure: the API returns 503; Refresh recovers.
- Delete a sample customer after confirmation.
- Restart the server to return to the initial two records.
Endpoint reference
| Method | Path | Result |
|---|---|---|
| GET | /api/health | 200 health object |
| GET | /api/customers?q=alex | 200 { items, total } |
| GET | /api/customers/:id | 200 customer or 404 |
| POST | /api/customers | 201 created customer |
| PATCH | /api/customers/:id | 200 updated customer |
| DELETE | /api/customers/:id | 204 with no body |
| POST | /api/reset | Restore initial in-memory customers |
| GET | /api/customers?fail=1 | 503 simulated failure |
Fields: name (1–80 characters), email (valid format, unique), plan (Starter/Growth/Scale), status (Active/Trial/Archived). The server ignores client IDs on create. PATCH retains unspecified fields. Malformed JSON returns 400; invalid fields return 422.
Test from PowerShell
$base = 'http://127.0.0.1:5188/api'
Invoke-RestMethod "$base/customers"
$body = @{ name='Taylor Demo'; email='taylor@example.com'; plan='Growth'; status='Trial' } | ConvertTo-Json
$created = Invoke-RestMethod "$base/customers" -Method Post -ContentType 'application/json' -Body $body
Invoke-RestMethod "$base/customers/$($created.id)" -Method Patch -ContentType 'application/json' -Body '{"status":"Active"}'
Invoke-RestMethod "$base/customers/$($created.id)" -Method DeleteConnect HTML or write your own client
The runnable client source is included for inspection. Run it through /client, not file://, because its requests use relative /api URLs. When adding an API screen to the HTML template, use an absolute local API base while the UI runs on its own localhost port:
async function getCustomers(signal) {
const response = await fetch('http://127.0.0.1:5188/api/customers', { signal });
const body = await response.json();
if (!response.ok) throw new Error(body.error || 'Request failed');
return body.items;
}
// After core.js and an empty #records div exist:
getCustomers().then(rows => Navrenza.table(document.querySelector('#records'), {
rows, label: 'Customers', columns: [
{ key: 'name', label: 'Name' }, { key: 'email', label: 'Email' }
]
})).catch(error => Navrenza.notice(error.message, true));CORS and real hosting
The mock API permits local HTTP origins on localhost and 127.0.0.1. file:// requests are rejected; use the included /client URL or the HTML localhost helper. Replace the mock API with your own authenticated, persistent service before production. Do not deploy the teaching server as your real backend.