Test the API
Verify the generated route surface before connecting a frontend or adding custom logic. The TypeScript template exposes Swagger UI and NestJS CRUD-compatible resource endpoints.
Open Swagger UI
Start the service:
apso devFor a TypeScript project using the template’s default port, open:
http://localhost:3100/_docsSwagger shows the exact plural route names, request schemas, response schemas, and available operations for the current generation.
Set a base URL
export APSO_API_URL=http://localhost:3100If the API requires a service key, add it to each request:
export APSO_API_KEY=replace-with-your-keyExercise CRUD
Create
curl -s -X POST "$APSO_API_URL/Projects" \
-H "Content-Type: application/json" \
-H "X-API-Key: $APSO_API_KEY" \
-d '{"name":"API verification","status":"Active"}'List
curl -s "$APSO_API_URL/Projects?limit=20&page=1" \
-H "X-API-Key: $APSO_API_KEY"Generated list routes use paginated responses when pagination is enabled:
{
"data": [],
"count": 0,
"total": 0,
"page": 1,
"pageCount": 0
}Get one
curl -s "$APSO_API_URL/Projects/1" \
-H "X-API-Key: $APSO_API_KEY"Update
curl -s -X PATCH "$APSO_API_URL/Projects/1" \
-H "Content-Type: application/json" \
-H "X-API-Key: $APSO_API_KEY" \
-d '{"status":"Archived"}'Delete
curl -s -X DELETE "$APSO_API_URL/Projects/1" \
-H "X-API-Key: $APSO_API_KEY"Remove the X-API-Key header for an unprotected local service. For end-user authentication, send the access token expected by your configured auth provider.
Test filters and sorting
The generated TypeScript API uses NestJS CRUD query syntax.
# Filter by status
curl -s "$APSO_API_URL/Projects?filter=status||\$eq||Active"
# Sort newest first
curl -s "$APSO_API_URL/Projects?sort=created_at,DESC"
# Combine filter, sort, and pagination
curl -s "$APSO_API_URL/Projects?filter=status||\$eq||Active&sort=created_at,DESC&limit=10&page=1"Common operators:
| Operator | Meaning | Example |
|---|---|---|
$eq | Equal | `filter=status |
$ne | Not equal | `filter=status |
$cont | Contains | `filter=name |
$in | In a set | `filter=status |
$gt | Greater than | `filter=priority |
$isnull | Is null | `filter=archived_at |
Join a relationship
If the schema gives Projects a tasks relationship and the generated controller permits that join:
curl -s "$APSO_API_URL/Projects/1?join=tasks"Check /_docs or the generated controller before relying on a relationship name. The name comes from .apsorc relationship configuration.
Test with the SDK
import { ApsoClientFactory } from '@apso/sdk';
const apso = ApsoClientFactory.getClient({
baseURL: process.env.APSO_API_URL!,
apiKey: process.env.APSO_API_KEY!,
});
const projects = await apso.entity('Projects')
.where({ status: { $eq: 'Active' } })
.orderBy({ created_at: 'DESC' })
.limit(10)
.findMany();Check expected failures
Test more than successful requests:
| Case | Expected result |
|---|---|
| Missing required field | 400 or 422 validation response |
| Missing or invalid credential | 401 |
| Authenticated without permission | 403 |
| Unknown record ID | 404 |
| Conflicting unique value | 409 or database constraint response |
| Invalid filter or join | 400 |
Debug a failed request
curl -v "$APSO_API_URL/Projects?limit=5" \
-H "X-API-Key: $APSO_API_KEY"Record the method, URL, request body, response status, and response body. Remove credentials before sharing logs.