Skip to Content
Apso is in public beta. Get started
ArchitecturePlatform

Platform architecture

Apso separates product intent, generated framework code, custom behavior, and deployment operations. This makes schema changes reviewable and keeps the resulting backend usable as a standard framework project.

Core flow

Apso foundation mapOne product contract. A backend your team can own.
Owned output
01
Product intent

Describe the behavior

Actors, records, permissions, tenant boundaries, and the workflows they need.

02
Schema contract

Define the model

.apsorc

Entities, fields, relationships, auth strategy, indexes, and scope.

03
Consistent generation

Build the service

NestJSFastAPIGin

APIs, migrations, guards, tests, infrastructure, and OpenAPI.

04
Product code

Extend, run, and own

src/extensions/

Add product behavior, connect the client, and deploy wherever you choose.

Repeatable structureReviewable changesPortable codebase
BoundaryResponsibility
Product briefDescribe the application domain and first user workflow.
.apsorcDefine entities, fields, relationships, auth, scoping, and generation settings.
CLIParse, validate, generate, diagnose, test migrations, and coordinate platform actions.
Language generatorProduce NestJS and TypeORM, FastAPI and SQLAlchemy, or Gin and GORM source.
autogen/Hold replaceable framework layers derived from the schema.
extensions/Hold product-specific endpoints, hooks, integrations, and business rules.
RepositoryRecord the schema, generated diff, migrations, extensions, dependencies, and tests.
RuntimeRun locally, in Apso Cloud, or in infrastructure owned by the team.

Generation path

apso generate reads .apsorc, resolves the target language, validates generator compatibility, builds the relationship map, and writes the generated layers in the configured rootFolder.

For a REST entity, the generator creates the framework-native equivalents of:

  • Persistence model
  • Create and update request types
  • CRUD service
  • HTTP controller or handler when http is enabled
  • Module or route registration
  • Relationship wiring
  • Auth and scoping support when configured

The exact filenames differ by framework. The ownership rule remains the same: generated layers can be replaced, and extensions are preserved.

Request path

Request lifecycleOne request, with every backend boundary visible.
Authenticated
  1. 01ClientServer component, mobile app, or service
  2. 02SDK or RESTTyped operation and validated payload
  3. 03IdentitySession, JWT, or API key context
  4. 04Tenant scopeAuthorization and row boundary
  5. 05ServiceGenerated route, product logic, and database
Keep privileged credentials on the server and pass only verified identity and tenant context into the generated service.

When auth and scopeBy are configured, the request identity supplies fields such as workspaceId. The generated scope layer filters reads, injects scope on create, and verifies ownership for single-record operations. Extensions add product rules around this base behavior.

Local runtime

apso dev detects the language and database configuration from .apsorc and .env. It starts the native development command, or Docker when --docker is provided. The generated service exposes its OpenAPI surface at /_docs.

apso migrate compares schema snapshots, creates migration SQL, and runs the change against a local PGlite sandbox. This gives the developer a reviewable database impact before deployment.

Cloud deployment

For a linked service, apso deploy:

  1. Verifies CLI authentication and the local project link.
  2. Parses .apsorc and runs the migration sandbox unless skipped.
  3. Synchronizes local source to the connected GitHub repository unless skipped.
  4. Triggers the Apso build.
  5. Waits for the build result unless --no-wait is set.

The platform build provisions the service through an ordered workflow covering initialization, codebase preparation, database resources, and the application cloud stack. Build status is returned to the CLI and dashboard.

The cloud workflow consumes the same source repository the team can inspect and run locally. Generated code does not require a proprietary Apso runtime after generation.

System components

ComponentRole
Web applicationService builder, schema editor, code editor, credentials, environment, docs, deployment, and billing UI.
Platform APIWorkspaces, services, users, schema state, billing, and platform CRUD.
CLILocal generation and the developer interface to platform operations.
Build engineOrdered provisioning and build orchestration.
Service templatesFramework baselines used before entity-specific generation.
SDKTypeScript client for generated REST resources.

Failure boundaries

  • Schema validation stops before generation.
  • A generator failure leaves the reviewed schema as the source for diagnosis.
  • A migration failure stops deployment before the remote build.
  • An extension build failure does not require changes to generated files.
  • Use apso status and apso logs to diagnose a platform failure.
Last updated on