Skip to Content
Apso is in public beta. Get started
ConnectTest the API

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 dev

For a TypeScript project using the template’s default port, open:

http://localhost:3100/_docs

Swagger 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:3100

If the API requires a service key, add it to each request:

export APSO_API_KEY=replace-with-your-key

Exercise 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:

OperatorMeaningExample
$eqEqual`filter=status
$neNot equal`filter=status
$contContains`filter=name
$inIn a set`filter=status
$gtGreater than`filter=priority
$isnullIs 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:

CaseExpected result
Missing required field400 or 422 validation response
Missing or invalid credential401
Authenticated without permission403
Unknown record ID404
Conflicting unique value409 or database constraint response
Invalid filter or join400

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.

Last updated on