Every Shaperail project has a single configuration file named shaperail.config.yaml in the project root. This file controls the HTTP server, database, cache, authentication, storage, logging, and event routing for the entire service.

Minimal config

The only required field is project:

project: my-app

With nothing else specified, the server starts on port 3000 with automatic worker detection and no database, cache, or auth.

Full annotated example

project: my-api
port: 8080
workers: 4

database:
  type: postgresql
  host: ${DB_HOST:localhost}
  port: 5432
  name: my_api_db
  pool_size: 20

cache:
  type: redis
  url: redis://${REDIS_HOST:localhost}:6379

auth:
  provider: jwt
  secret_env: JWT_SECRET
  expiry: 24h
  refresh_expiry: 30d

storage:
  provider: s3
  bucket: my-bucket
  region: us-east-1

logging:
  level: info
  format: json
  otlp_endpoint: http://localhost:4317

events:
  subscribers:
    - event: "user.created"
      targets:
        - type: webhook
          url: "https://example.com/hooks/user-created"
        - type: job
          name: send_welcome_email
        - type: channel
          name: notifications
          room: "org:{org_id}"
        - type: hook
          name: validate_org
  webhooks:
    secret_env: WEBHOOK_SECRET
    timeout_secs: 30
    max_retries: 3
  inbound:
    - path: /webhooks/stripe
      secret_env: STRIPE_WEBHOOK_SECRET
      events: ["payment.completed", "subscription.updated"]

Section reference

project

Field Type Required Default Description
project string yes Project name. Used for logging, Docker image tags, and the generated crate name.

port

Field Type Required Default Description
port integer no 3000 TCP port the HTTP server binds to.

workers

Field Type Required Default Description
workers "auto" or integer no auto Number of Actix-web worker threads. auto uses the number of CPU cores.

database

Optional. When omitted, no database pool is created.

Field Type Required Default Description
type string yes Database engine. Use postgresql.
host string no localhost Database server hostname.
port integer no 5432 Database server port.
name string yes Database name.
pool_size integer no 20 Maximum connections in the sqlx pool.

cache

Optional. When omitted, no Redis connection is created.

Field Type Required Default Description
type string yes Cache backend. Use redis.
url string yes Redis connection URL (e.g., redis://localhost:6379).

auth

Optional. When omitted, endpoints that declare auth will fail validation.

Field Type Required Default Description
provider string yes Auth strategy. Use jwt.
secret_env string yes Name of the environment variable holding the signing secret.
expiry string yes Token lifetime (e.g., 24h, 60m).
refresh_expiry string no Refresh token lifetime (e.g., 30d). Omit to disable refresh tokens.

storage

Optional. When omitted, file upload endpoints are unavailable.

Field Type Required Default Description
provider string yes Storage backend: s3, gcs, or local.
bucket string no Bucket or container name. Required for s3 and gcs.
region string no Cloud region (e.g., us-east-1). Required for s3.

logging

Optional. Defaults to info-level JSON logs with no OTLP export.

Field Type Required Default Description
level string no info Log level: debug, info, warn, or error.
format string no json Output format: json or pretty.
otlp_endpoint string no OpenTelemetry collector endpoint (e.g., http://localhost:4317). Omit to disable trace export.

events

Optional. Controls event subscribers, outbound webhook settings, and inbound webhook endpoints.

events.subscribers

A list of event routing rules. Each entry maps an event name to one or more targets.

events:
  subscribers:
    - event: "user.created"
      targets:
        - type: job
          name: send_welcome_email
        - type: webhook
          url: "https://example.com/hooks/user-created"
        - type: channel
          name: notifications
          room: "org:{org_id}"
        - type: hook
          name: validate_org
Field Type Required Description
event string yes Event name pattern (e.g., user.created, *.deleted).
targets list yes One or more dispatch targets.

Each target has a type field that determines the remaining fields:

Target type Fields Description
job name Enqueue a background job by name.
webhook url POST to an external URL.
channel name, room (optional) Broadcast to a WebSocket channel. room scopes the broadcast.
hook name Execute a hook function.

events.webhooks

Global settings for outbound webhook delivery.

Field Type Required Default Description
secret_env string no WEBHOOK_SECRET Environment variable holding the HMAC signing secret.
timeout_secs integer no 30 HTTP timeout in seconds per delivery attempt.
max_retries integer no 3 Maximum retry attempts for failed deliveries.

events.inbound

A list of inbound webhook endpoints that Shaperail registers as routes.

Field Type Required Description
path string yes URL path (e.g., /webhooks/stripe).
secret_env string yes Environment variable holding the verification secret.
events list of strings no Event names this endpoint accepts. Empty means all events.

Environment variable interpolation

Use ${VAR} to inject an environment variable at parse time. Use ${VAR:default} to provide a fallback when the variable is unset.

project: ${APP_NAME:my-app}
database:
  type: postgresql
  host: ${DB_HOST:localhost}
  name: ${DB_NAME}

Rules:

  • ${DB_NAME} – if DB_NAME is not set, the parser returns an error naming the missing variable.
  • ${DB_HOST:localhost} – if DB_HOST is not set, localhost is used.
  • ${} – empty placeholders are rejected.
  • Unterminated ${... without a closing } is rejected.

Interpolation happens before YAML parsing, so the substituted value becomes part of the raw YAML text.

Validation rules

Shaperail rejects invalid configuration at startup with a clear error message.

  • project is required. Omitting it produces a “missing field” error.
  • Unknown fields are rejected. Every section uses deny_unknown_fields. A typo like databse: instead of database: produces an “unknown field” error listing the valid alternatives.
  • Type mismatches fail. Setting port: "not-a-number" or workers: [] produces a deserialization error.
  • Missing env vars fail. A ${VAR} reference with no default and no matching environment variable halts parsing with a message naming the variable.

Back to top

Shaperail documentation lives in the same repository as the framework so every release has versioned instructions.

This site uses Just the Docs, a documentation theme for Jekyll.