Skip to content

Adapter

Adapter is the Infrastructure implementation of a Domain Contract at an outbound boundary. It translates vendor or framework failures into Domain exceptions.

Generated facts

Layer
infrastructure
Generated path
app/Pulsar/Infrastructure/{Area}/{Name}.php
Generator command
make:adapter
Workflow method
None
Stability
Current manifest surface (Pulsar 0.4.1)

Canonical example

Generated src/stubs/adapter.stub — canonical synchronized stub.

<?php

namespace {{namespace}};

{{contractImport}}

class {{name}} {{implements}}
{
    // Translate vendor/framework errors into Domain exceptions at this boundary.
    // Make retryable side effects idempotent.
    // Bind in PulsarServiceProvider: $this->app->bind({{contract}}::class, {{name}}::class);
}

Responsibility

Adapter owns the responsibility stated above; it must not absorb delivery, transaction, or unrelated cross-layer behavior.

Placement and dependencies

Keep this type in Infrastructure. It implements a Domain-owned Contract and must translate vendor or framework failures at the boundary.

Workflow and tests

Adapter is consumed by the owning Domain or Service workflow and returns a delivery-neutral result. Test its direct contract, its rejected boundary cases, and the caller or callee that proves the rule in application flow.

Three pitfalls

  1. ❌ Prohibited: move this responsibility into a neighboring type merely because it is nearby.
  2. ✅ Correct: keep the generated placement and depend only on the documented layer direction.
  3. ✅ Correct: test the boundary through the caller and the return or side effect visible to its callee.

Boundaries

❌ Prohibited: Import an Adapter into a Domain Contract or add transaction and branching business logic to the Adapter.

✅ Correct: Keep the Contract Domain-owned, bind the concrete Adapter in PulsarServiceProvider::register(), and let a UseCase own transaction boundaries.

Read Contracts and Adapters for the architecture rule and provider wiring for the binding location.