Setting Up Backends
Prerequisites
Load engineering-principles and architecting-changes before this skill.
They provide the foundation: strict tooling, boundary rules, reusable cores,
and framework-over-ad-hoc defaults.
Load setting-up-projects first for general project bootstrap (directory
structure, setup checklist, domain adaptation). This skill adds the
backend-specific layer: service layout, app factory, wiring, and
infrastructure deferral.
Default Approach
Choose framework weight:
- Default to the boring, well-maintained framework for your ecosystem.
- Heavier framework justified when auth, admin, sessions, and CRUD are
obviously present and important from the start.
- Thin-edge framework for deliberate minimal builds, not as a default.
Start with reusable core and thin transport: routes, workers,
schedulers, CLI hooks, and automation all call the same core services.
Business logic lives in the domain layer, not in HTTP handlers.
Add infrastructure only when needed: relational DB, auth, outbound
HTTP, cache/jobs — each only when the project actually needs it. Do not
pre-install infrastructure for hypothetical future needs.
Keep one composition root and one app factory: single place where all
wiring happens. No scattered initialization, no hidden side effects in
module imports.
Default Stack Philosophy
Pick a standard, well-maintained stack for your ecosystem. The stack should
be boring, well-documented, and widely adopted.
- Keep transport-layer DTOs/schemas at the HTTP boundary — convert
immediately into framework-free typed structures. Request/response shapes
are not domain models.
- Framework handles transport, serialization, routing, lifecycle. Your code
handles business logic. When framework knowledge dominates the codebase,
the separation is wrong.
- One task runner for all dev commands (run, lint, test, migrate). Every
operation should be reproducible with a single command.
Default Layout
Omit what you do not need. No DB → no db/ or migrations/. No workers →
no workers/. Start minimal and add directories only when the project
demands them. This layout is an example, not a mandatory template.
src/appname/
api/ # HTTP layer only
app # App factory
routes/ # Route handlers
schemas/ # Request/response DTOs
errors # HTTP error mapping
domain/ # Business logic (framework-free)
models # Domain data types
services # Use cases / operations
errors # Domain error types
infrastructure/ # External concerns
config # Typed settings from env/files
logging # Logging setup
db/ # Database access (models, session, queries)
clients/ # External API clients
workers/ # Background job handlers
entrypoint # Worker process entry
bootstrap # Composition root — wires everything together
tests/
integration/
unit/
fixtures/
migrations/ # If owning a relational DB
First Files
Create these early to establish the skeleton before adding features:
- API entrypoint with app factory function
- Health check endpoint (e.g.
/healthz)
- Bootstrap/composition-root module that wires services
- Domain models and one small service/use-case/handler module
- Config module to parse environment into typed settings
- DB files and migrations only if persistence exists
- One smoke API test and one domain test
The smoke test proves the app starts and the health endpoint responds. The
domain test proves one piece of business logic works. Together they verify
the wiring is correct before any real features are built.
Wiring Rules
- App factory assembles only the transport/HTTP layer — routes,
middleware, error handlers. It does not know about database connections or
business logic.
- Bootstrap/composition root wires settings, DB/session factories,
external clients, and services. This is the single place where all
dependencies are connected.
- Keep entrypoints thin — the main/server entrypoint does only the final
handoff to the app factory. It imports, calls, and exits.
- Domain classes never instantiate their own infrastructure — pass
everything via constructor. A service that creates its own database
connection is untestable and couples business logic to infrastructure.
Boundary Rules
- Request/response schemas are not domain models.
- No
Request, Response, Depends, ORM session, or framework auth objects in domain services.
- Convert request data and auth/session state at the edge.
- Workers are another adapter, not a separate business-logic stack.
- CLI/admin scripts should call the same core services when they touch the same workflows.
Defer by Default
Add these only when the project/specs really needs them:
- queues and background-job stacks
- caching layers
- metrics/tracing vendors
- event buses or CQRS
- multitenancy
- API versioning strategy beyond basic room for growth
- generated SDKs and OpenAPI customization
- Kubernetes-specific guidance
Each deferred item is real infrastructure with real operational cost. The
default is to defer until a concrete feature demands it. Pre-installing
infrastructure for hypothetical needs adds complexity without value.
Migrations and Operations
- If the service owns a relational DB, initialize migrations early. The
first migration should create the initial schema; every subsequent schema
change gets its own migration.
- Add health and readiness endpoints early. Health answers "is the process
alive?" Readiness answers "can it serve traffic?" (DB reachable, caches
warm, etc.)
- Keep all dev commands (run, lint, test, migrate) in the task runner. No
ad-hoc shell scripts scattered across the repo.
- Containerize when needed, but keep v1 simple and boring (Linux-first). Do
not build a multi-arch container pipeline before the first deployment.
Handoff
After bootstrap, use these skills for deeper decisions:
building-backends — for backend architecture patterns: thin transport,
reusable core, transaction ownership, auth boundaries, workers, and common
backend mistakes.
architecting-changes — for architecture decisions about service
boundaries, pattern selection, and infrastructure choices.
api-design — for stable API and protocol/interface design at the HTTP
boundary.
security-and-hardening — for auth, secrets, and boundary hardening in
backend services.
Related myai Skills
engineering-principles — Parent skill. Language-agnostic project
setup philosophy and architecture principles.
architecting-changes — Parent skill. Architecture decision framework
for backend shape, boundaries, and pattern selection.
building-backends — Backend architecture patterns: thin transport,
reusable core, transaction ownership, auth boundaries, and workers.
setting-up-projects — General project bootstrap (directory structure,
setup checklist, domain adaptation). Load before this skill.
api-design — For stable API and protocol/interface design.
security-and-hardening — For auth, secrets, and boundary hardening.
ci-cd-and-automation — For CI/CD pipeline setup after bootstrap.
Language-Specific Extensions
After applying the patterns in this skill, load the appropriate
language-specific extension for concrete framework choices, library
selections, config templates, and code examples:
- Python:
setting-up-python-backends — FastAPI/Django/Starlette choice,
SQLAlchemy + Alembic, pydantic at edge, httpx, default stack,
Python-specific layout with file names
- Other ecosystems: if no language-specific skill exists, apply the
patterns above with
engineering-principles ecosystem examples as a
starting point, and record the gap for follow-up
When a language-specific extension is available, load this skill first for
the patterns and decision framework, then the extension for concrete tooling.
1---2name: setting-up-backends3description: ALWAYS LOAD THIS SKILL WHEN BOOTSTRAPPING A NEW BACKEND, API SERVICE, OR WORKER REPO FOR ANY LANGUAGE OR ECOSYSTEM. Do not scaffold backends directly — use this skill first. Backend/service directory layout, app factory pattern, wiring rules, defer-by-default infrastructure, and service-first project conventions.4license: MIT5---67# Setting Up Backends89## Prerequisites1011Load `engineering-principles` and `architecting-changes` before this skill.12They provide the foundation: strict tooling, boundary rules, reusable cores,13and framework-over-ad-hoc defaults.1415Load `setting-up-projects` first for general project bootstrap (directory16structure, setup checklist, domain adaptation). This skill adds the17backend-specific layer: service layout, app factory, wiring, and18infrastructure deferral.1920---2122## Default Approach23241. **Choose framework weight**:25 - Default to the boring, well-maintained framework for your ecosystem.26 - Heavier framework justified when auth, admin, sessions, and CRUD are27 obviously present and important from the start.28 - Thin-edge framework for deliberate minimal builds, not as a default.29302. **Start with reusable core and thin transport**: routes, workers,31 schedulers, CLI hooks, and automation all call the same core services.32 Business logic lives in the domain layer, not in HTTP handlers.33343. **Add infrastructure only when needed**: relational DB, auth, outbound35 HTTP, cache/jobs — each only when the project actually needs it. Do not36 pre-install infrastructure for hypothetical future needs.37384. **Keep one composition root and one app factory**: single place where all39 wiring happens. No scattered initialization, no hidden side effects in40 module imports.4142---4344## Default Stack Philosophy4546Pick a standard, well-maintained stack for your ecosystem. The stack should47be boring, well-documented, and widely adopted.4849- Keep transport-layer DTOs/schemas at the HTTP boundary — convert50 immediately into framework-free typed structures. Request/response shapes51 are not domain models.52- Framework handles transport, serialization, routing, lifecycle. Your code53 handles business logic. When framework knowledge dominates the codebase,54 the separation is wrong.55- One task runner for all dev commands (run, lint, test, migrate). Every56 operation should be reproducible with a single command.5758---5960## Default Layout6162Omit what you do not need. No DB → no `db/` or `migrations/`. No workers →63no `workers/`. Start minimal and add directories only when the project64demands them. This layout is an example, not a mandatory template.6566```text67src/appname/68 api/ # HTTP layer only69 app # App factory70 routes/ # Route handlers71 schemas/ # Request/response DTOs72 errors # HTTP error mapping73 domain/ # Business logic (framework-free)74 models # Domain data types75 services # Use cases / operations76 errors # Domain error types77 infrastructure/ # External concerns78 config # Typed settings from env/files79 logging # Logging setup80 db/ # Database access (models, session, queries)81 clients/ # External API clients82 workers/ # Background job handlers83 entrypoint # Worker process entry84 bootstrap # Composition root — wires everything together85tests/86 integration/87 unit/88 fixtures/89migrations/ # If owning a relational DB90```9192---9394## First Files9596Create these early to establish the skeleton before adding features:9798- API entrypoint with app factory function99- Health check endpoint (e.g. `/healthz`)100- Bootstrap/composition-root module that wires services101- Domain models and one small service/use-case/handler module102- Config module to parse environment into typed settings103- DB files and migrations only if persistence exists104- One smoke API test and one domain test105106The smoke test proves the app starts and the health endpoint responds. The107domain test proves one piece of business logic works. Together they verify108the wiring is correct before any real features are built.109110---111112## Wiring Rules113114- **App factory** assembles only the transport/HTTP layer — routes,115 middleware, error handlers. It does not know about database connections or116 business logic.117- **Bootstrap/composition root** wires settings, DB/session factories,118 external clients, and services. This is the single place where all119 dependencies are connected.120- **Keep entrypoints thin** — the main/server entrypoint does only the final121 handoff to the app factory. It imports, calls, and exits.122- **Domain classes never instantiate their own infrastructure** — pass123 everything via constructor. A service that creates its own database124 connection is untestable and couples business logic to infrastructure.125126---127128## Boundary Rules129130- Request/response schemas are not domain models.131- No `Request`, `Response`, `Depends`, ORM session, or framework auth objects in domain services.132- Convert request data and auth/session state at the edge.133- Workers are another adapter, not a separate business-logic stack.134- CLI/admin scripts should call the same core services when they touch the same workflows.135136---137138## Defer by Default139140Add these only when the project/specs really needs them:141142- queues and background-job stacks143- caching layers144- metrics/tracing vendors145- event buses or CQRS146- multitenancy147- API versioning strategy beyond basic room for growth148- generated SDKs and OpenAPI customization149- Kubernetes-specific guidance150151Each deferred item is real infrastructure with real operational cost. The152default is to defer until a concrete feature demands it. Pre-installing153infrastructure for hypothetical needs adds complexity without value.154155---156157## Migrations and Operations158159- If the service owns a relational DB, initialize migrations early. The160 first migration should create the initial schema; every subsequent schema161 change gets its own migration.162- Add health and readiness endpoints early. Health answers "is the process163 alive?" Readiness answers "can it serve traffic?" (DB reachable, caches164 warm, etc.)165- Keep all dev commands (run, lint, test, migrate) in the task runner. No166 ad-hoc shell scripts scattered across the repo.167- Containerize when needed, but keep v1 simple and boring (Linux-first). Do168 not build a multi-arch container pipeline before the first deployment.169170---171172## Handoff173174After bootstrap, use these skills for deeper decisions:175176- `building-backends` — for backend architecture patterns: thin transport,177 reusable core, transaction ownership, auth boundaries, workers, and common178 backend mistakes.179- `architecting-changes` — for architecture decisions about service180 boundaries, pattern selection, and infrastructure choices.181- `api-design` — for stable API and protocol/interface design at the HTTP182 boundary.183- `security-and-hardening` — for auth, secrets, and boundary hardening in184 backend services.185186---187188## Related myai Skills189190- **`engineering-principles`** — Parent skill. Language-agnostic project191 setup philosophy and architecture principles.192- **`architecting-changes`** — Parent skill. Architecture decision framework193 for backend shape, boundaries, and pattern selection.194- **`building-backends`** — Backend architecture patterns: thin transport,195 reusable core, transaction ownership, auth boundaries, and workers.196- **`setting-up-projects`** — General project bootstrap (directory structure,197 setup checklist, domain adaptation). Load before this skill.198- **`api-design`** — For stable API and protocol/interface design.199- **`security-and-hardening`** — For auth, secrets, and boundary hardening.200- **`ci-cd-and-automation`** — For CI/CD pipeline setup after bootstrap.201202---203204## Language-Specific Extensions205206After applying the patterns in this skill, load the appropriate207language-specific extension for concrete framework choices, library208selections, config templates, and code examples:209210- **Python**: `setting-up-python-backends` — FastAPI/Django/Starlette choice,211 SQLAlchemy + Alembic, pydantic at edge, httpx, default stack,212 Python-specific layout with file names213- **Other ecosystems**: if no language-specific skill exists, apply the214 patterns above with `engineering-principles` ecosystem examples as a215 starting point, and record the gap for follow-up216217When a language-specific extension is available, load this skill first for218the patterns and decision framework, then the extension for concrete tooling.