Code generation
Code generation turns the version 2 .apsorc contract into framework-native persistence and API layers. It handles repeatable structure so the team can spend its custom code budget on product behavior.
Reproducible foundation
src/autogen/entities/src/autogen/controllers/src/autogen/dtos/migrations/Change the contract, validate it, and generate the same framework structure again.
Preserved product logic
src/extensions/src/integrations/src/workflows/tests/Keep approvals, billing rules, integrations, and other product decisions in normal framework code.
Inputs
The generator uses:
- Target language from
--languageor.apsorc - Entities and fields
- Top-level relationship objects
- Auth and tenant-scoping settings
- HTTP and domain-event controls
- Existing framework template files
Generated output
For each entity, Apso can produce the target framework’s model, request types, service, CRUD controller or handler, and module or route registration. Shared output can include enum types, query helpers, auth guards, and relationship wiring.
| Language | Framework layers |
|---|---|
| TypeScript | NestJS, TypeORM, class-validator, Swagger/OpenAPI |
| Python | FastAPI, SQLAlchemy, Pydantic, OpenAPI |
| Go | Gin, GORM, request models, OpenAPI support |
Safe iteration
Change the schema
Edit .apsorc, keeping the change focused on one product behavior or migration.
Validate
apso schema validateGenerate
apso generateUse an explicit language to test another target:
apso generate --language pythonReview the diff
git diff -- .apsorc src/autogenCheck route names, fields, relationship direction, imports, and module registration.
Test the database change
apso migrateRun framework checks
Run the generated project’s tests and build, then exercise the changed route in /_docs.
Regeneration can replace files under autogen/. Keep custom endpoints, integrations, hooks, and business rules under extensions/ and commit before generating.
Generation is a baseline
Generated CRUD does not encode every product decision. Add extension code for calculations, workflow transitions, provider calls, approvals, notifications, and policies that depend on more than schema structure.
When to regenerate
Regenerate after changing an entity, field, relationship, auth setting, scoping rule, language target, or generation control. You do not need to regenerate for a change contained entirely in extensions/.
