Request lifecycle

An adapter translates one protocol into calls on application contracts. It owns HTTP concerns; it does not own business rules or SQL.

flowchart LR
  C["Client"] --> A["Transport adapter"]
  A --> H["Authenticate and parse"]
  H --> O["operation::check"]
  O --> S["Contract service"]
  S --> I["Implementation"]
  I --> P["Provider: database, cache, service"]
  S --> R["Return value or AppError"]
  R --> A
  A --> C

1. The adapter receives the request

The adapter:

  • extracts path, query, headers, cookies, and body;
  • authenticates credentials at the edge;
  • builds a trusted CallContext only after authentication succeeds;
  • validates and maps transport errors.

It calls the contract. It never imports the concrete database or policy crate.

2. The operation checks access and validates input

rust
iet_core::operation::check::<CreateNote, _>(&authorizer, &context, &input).await?;

Access is enforced before validation. A denied caller cannot reach Validate::validate. See Contracts and traits and Calls and transactions.

3. The contract service performs the work

The service depends on ports, not providers. It may:

  • call repository methods on a shared Session;
  • open a TransactionScope when several statements must succeed together;
  • use a cache or another capability through its contract;
  • return a domain value or a structured AppError.

4. The implementation carries out storage or policy

An implementation such as iet-db-timescale provides the Session, repository, and transaction machinery. Policy crates such as iet-auth-rbac implement authorization ports.

The implementation knows its provider. It does not know which adapter called it.

5. The adapter maps the result

The adapter maps domain values and AppError kinds to its protocol:

ErrorKindHTTP mapping
Validation422 Unprocessable Entity
Unauthenticated401 Unauthorized
Forbidden403 Forbidden
NotFound404 Not Found
Conflict409 Conflict
Unavailable503 Service Unavailable
DeadlineExceeded504 Gateway Timeout
Internal500 Internal Server Error

The transport adapter owns the mapping. Core does not encode HTTP.

What stays out of the adapter

  • Business rules and invariants.
  • SQL and migrations.
  • Policy decisions about roles or resource grants.
  • Session or transaction lifetime beyond what the contract requires.

What stays out of the contract

  • HTTP status codes, headers, cookies, and HTML.
  • A concrete database, cache, or message broker.
  • Framework-specific runtime types.

That separation is what makes the same capability callable from an HTMX page, a JSON API, a command-line tool, or a background worker.

IET Framework documentation — built with the IET Framework.