Files
apophis-fastify/docs/getting-started.md
T
John Dvorak dc7a4205ec fix: correct documented vs actual behavior discrepancies from subworker audit
- Fix verify.md --changed exit code (0 → 2)
- Add 'deep' as alias for 'thorough' in generation profile resolution
- Fix PLUGIN_CONTRACTS_SPEC status: Partially implemented (registry done, runner pending)
- Fix OUTBOUND_CONTRACT_MOCKING_SPEC status: Implemented (Phase 1)
- Fix cli.md environment matrix to match actual code granularity
- Fix chaos.md: document delay handler is currently a no-op
- Fix getting-started.md warning: note APOPHIS does not proactively detect nondeterminism
- Add variants section to getting-started.md
- Build: clean | Tests: 849 pass, 0 fail
2026-04-30 11:50:39 -07:00

3.8 KiB

Getting Started with APOPHIS

Get from install to your first behavioral bug in 10 minutes.

APOPHIS is inspired by Invariant-Driven Automated Testing (Malhado Ribeiro, 2021): instead of only validating request and response shape, encode intended behavior as executable contracts and let the tool find violations automatically.

Prerequisites

  • Node.js 20.x or 22.x
  • A Fastify app with @fastify/swagger registered

Step 1: Install

npm install apophis-fastify fastify @fastify/swagger

Step 2: Scaffold

apophis init --preset safe-ci

This creates:

  • apophis.config.js — config with a quick profile
  • APOPHIS.md — preset-specific guidance
  • Package script: npm run apophis:verify

Step 3: Add One Behavioral Contract

Pick one important route. Add an x-ensures clause that checks behavior across operations:

import crypto from 'crypto';

app.post('/users', {
  schema: {
    'x-category': 'constructor',
    'x-ensures': [
      // BEHAVIORAL: Creating a user must make it retrievable
      'response_code(GET /users/{response_body(this).id}) == 200'
    ]
  }
}, async (request, reply) => {
  const { name } = request.body;
  const id = `usr-${crypto.createHash('sha256').update(name).digest('hex').slice(0, 8)}`;
  reply.status(201);
  return { id, name };
});

Warning: Using Date.now() or Math.random() in handlers breaks determinism and replay. Use a stable function of the input instead. APOPHIS does not proactively detect nondeterministic handlers; it warns only when a replay diverges from the original run.

Step 4: Run Verify

apophis verify --profile quick --routes "POST /users"

Example Failure

If your GET /users/:id handler has a bug (always returns 404), APOPHIS catches it:

Contract violation
POST /users
Profile: quick
Seed: 42

Expected
  response_code(GET /users/{response_body(this).id}) == 200

Observed
  GET /users/usr-7d865e returned 404

Why this matters
  The resource created by POST /users is not retrievable.

Replay
  apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json

Next
  Check the create/read consistency for POST /users and GET /users/{id}.

Step 5: Replay and Fix

Copy the replay command and run it:

apophis replay --artifact reports/apophis/failure-2026-04-28T12-30-22Z.json

Fix the bug in your handler. Re-run verify. The failure should now pass.

Next Steps

  • Add more routes to your profile: apophis verify --profile quick --routes "POST /users,PUT /users/:id"
  • Use wildcards to match route patterns: apophis verify --routes 'POST /api/*'
  • Run all routes: apophis verify --profile quick
  • Run only changed routes in CI: apophis verify --profile ci --changed
    • Requires a git repository.
  • Use machine-readable output in CI: apophis verify --profile ci --format json-summary
  • Add observe mode for runtime drift detection: see observe.md
  • Add qualify mode for scenario, stateful, and chaos checks: see qualify.md

Variants

Test the same route with different headers or content types:

await fastify.apophis.contract({
  variants: [
    { name: 'json', headers: { accept: 'application/json' } },
    { name: 'xml', headers: { accept: 'application/xml' } }
  ]
})

Or declare variants in the route schema:

app.get('/users', {
  schema: {
    'x-variants': [
      { name: 'json', headers: { accept: 'application/json' } }
    ]
  }
})

Config Reference

For the full configuration reference, see CLI Reference.

Monorepo Workspaces

Use --workspace to run verify or doctor across all packages:

apophis verify --workspace --profile quick --format json

See CLI Reference for workspace output format and exit codes.