Skip to content

Tutorial

Open in ChatGPTOpen in Claude

This tutorial builds a REST backend end-to-end: scaffold, tour, synth, deploy, call the API, extend it, test it, and tear it down. It assumes you have completed Install and have AWS credentials ready (AWS Credentials & Bootstrap).

Terminal window
axs new my-api --template rest-v1
cd my-api

The CLI scaffolds the project, writes axis.json, initialises git, installs dependencies, and activates the git hooks. Answer the feature prompts however you like — every answer is reversible later (see Feature Toggles).

Two files at the root orient you (and any AI assistant you point at the project):

  • STRUCTURE.md — the human-readable narrative of the directory layout.
  • axis.json — the machine-readable manifest: starter, layout, paths, conventions.

The working tree splits into three areas — typed configuration in config/, stack composition in cdk/, and handler code in lambdas/. The full map is in Project Structure; the short version:

  • config/dev-config.ts / config/prod-config.ts — per-environment values.
  • config/lambdas.ts — the registry of API Lambda configs; config/tables/ — the table definitions.
  • cdk/bin/app.ts — instantiates the stacks, gated by config/features.ts.
  • lambdas/modules/health/api/check/index.ts — the scaffolded health-check handler.

Open config/dev-config.ts and review the seeded values before continuing.

Synthesis compiles your typed config into CloudFormation templates without touching AWS:

Terminal window
pnpm run cdk:synth

Inspect cdk.out/ if you’re curious — one template per stack. Synth is also where Axis validation fires: an invalid feature toggle, a missing registry entry, or an incoherent composer selection throws an [Axis]-prefixed error here, not at deploy time.

Terminal window
npx cdk bootstrap --context env=dev # one-time per account/region
pnpm run cdk:deploy # cdk deploy --all --context env=dev

When the deploy finishes, the API stack prints its human-readable outputs, including the API URL — these are plain CfnOutputs for copy-paste convenience, never CloudFormation exports.

The rest-v1 starter ships a public health route:

Terminal window
curl https://<your-api-id>.execute-api.<region>.amazonaws.com/dev/health

The item routes are Cognito-protected by default, so they answer 401 without a token — that’s the framework’s never-silently-public posture doing its job.

axs add reads axis.json and places new code where your project’s layout says it belongs:

Terminal window
axs add lambda items/create --kind api --method POST --path /items

In module layout this generates lambdas/modules/items/api/create/{index,service}.ts, a per-route config under config/lambda-configs/items/create.ts, a colocated test stub, and the registry import. The generated config is a typed ApiLambdaConfig — this is the exact POST /items route from the framework’s own example-rest-full, so what you author matches a synth-tested oracle:

export const createItemConfig: ApiLambdaConfig = {
kind: "api",
name: "create-item",
entry: "lambdas/modules/items/api/create/index.ts",
description: "Create an item",
method: "POST",
path: "/items",
authorizer: "cognito",
// Phase 3N: also require an API key (orthogonal to the cognito authorizer).
apiKey: true,
};

A re-synth picks it up:

Terminal window
pnpm run cdk:synth
pnpm run cdk:deploy

The scaffold ships tests/synth.test.ts — snapshot and assertion tests over the synthesized templates:

Terminal window
pnpm test

These are the same shape of tests the framework’s own examples run in CI; treat a snapshot diff as a question (“did I mean to change deployed infrastructure?”) rather than noise.

Terminal window
npx cdk destroy --all --context env=dev

Dev-stage stateful resources use DESTROY removal policies (with S3 auto-delete), so teardown is clean. Prod stages retain stateful resources by design — see The Five Pillars.

© 2026 Axis Tech. Powered by axis-tech.co.