Core Building Blocks

Command

Synchronous request/response handlers with typed schemas and validation

A command is the foundational building block of PURISTA. It is a synchronous request-response function inside a service that receives a request, performs work, and returns a result. Commands are how you expose business logic to the outside world — whether through HTTP, cross-service calls, or programmatic APIs.

Commands live inside services. A service groups related commands (and subscriptions and streams) around a single domain boundary like “User Management” or “Billing.” The service builder collects command definitions, and the event bridge routes incoming requests to the right handler.

Request/response semantics

A command always returns a result or an error. If you need fire-and-forget behavior, use a subscription instead. If you need continuous data flow, use a stream. If you need background work with retries, use a queue.

In this section

Quick reference

Command lifecycle

flowchart LR
    A[Incoming Request] --> B[Input Transform]
    B --> C[Payload & Parameter Validation]
    C --> D[Before Guards]
    D --> E[Command Function]
    E --> F[Output Validation]
    F --> G[After Guards]
    G --> H[Output Transform]
    H --> I[Response]
    C -.->|Invalid| J[Bad Request]
    D -.->|Denied| K[Unauthorized]
    E -.->|Error| L[Handled or Unhandled]
    F -.->|Invalid| M[Internal Error]

Key principles

  • Commands are request/response — they always return a result or error.
  • Schemas drive TypeScript inference throughout the pipeline.
  • Use async function, not arrow functions, to preserve this context.
  • Keep auth logic in guards, not inside the command function.
  • Choose the right handler: commands for sync work, queues for background work, subscriptions for events, streams for data flow.

Related

Read Next
Config Store

from Stores — Data Persistence