ADR - Domain¶
Overview¶
The domain is your application's business logic: entities, services, and the rules that operate on them. In ADR the domain is completely unaware of HTTP. It receives plain input, does its work, and returns a Payload describing what happened. Because it never touches the request or the response, the domain is simple to test and can be reused across HTTP, CLI, and queue contexts alike.
A domain implements no framework interface; it is simply your own class. It takes an input object and returns a Payload. Typing the input is up to you: the generic Input bag works out of the box, or you extend it into a typed, per-domain value object such as an InvoicesDto.
<?php
namespace MyApp\Domain;
use MyApp\Models\Invoices;
use Phalcon\ADR\Input\Input;
use Phalcon\ADR\Payload\Payload;
use Phalcon\Contracts\ADR\Payload\Payload as PayloadInterface;
final class ViewInvoice
{
public function __invoke(Input $input): PayloadInterface
{
$invoice = Invoices::findFirst($input->get('id'));
return $invoice === null
? Payload::notFound(['id' => $input->get('id')])
: Payload::success($invoice);
}
}
The Payload¶
Phalcon\ADR\Payload\Payload is an immutable value object that carries the outcome of the domain back to the responder. It never describes an HTTP response; it describes a domain result, which the responder is then free to translate. A payload holds a status plus, depending on that status, a result, a set of messages, an exception, the original input, and any extras.
It is created through named factories that pair an outcome with the right status:
| Factory | Status | Typical use |
|---|---|---|
Payload::success($result) |
SUCCESS |
a value was read or an operation completed |
Payload::created($result) |
CREATED |
a resource was created |
Payload::updated($result) |
UPDATED |
a resource was updated |
Payload::deleted($result) |
DELETED |
a resource was deleted |
Payload::found($result) |
FOUND |
a resource was located |
Payload::accepted($result) |
ACCEPTED |
work was accepted for later processing |
Payload::processing($result) |
PROCESSING |
work is in progress |
Payload::notFound($messages) |
NOT_FOUND |
a resource does not exist |
Payload::invalid($messages) |
NOT_VALID |
validation failed |
Payload::error($messages) |
ERROR |
an unexpected failure |
Payload::unauthenticated($messages) |
NOT_AUTHENTICATED |
identity was not established |
Payload::forbidden($messages) |
NOT_AUTHORIZED |
identity is known but not allowed |
The payload is immutable. Every with*() method (withStatus(), withResult(), withMessages(), withInput(), withExtras(), withException()) returns a new copy rather than mutating the original.
Status¶
Phalcon\ADR\Payload\Status is the domain's vocabulary of outcomes, expressed as string constants that carry no HTTP meaning:
ACCEPTED CREATED DELETED ERROR FAILURE FOUND METHOD_NOT_ALLOWED
NOT_ACCEPTED NOT_AUTHENTICATED NOT_AUTHORIZED NOT_CREATED NOT_DELETED
NOT_FOUND NOT_UPDATED NOT_VALID PROCESSING SUCCESS UPDATED VALID
AUTHENTICATED AUTHORIZED
Translating a status into an HTTP status code is the responder's job, performed by a status mapper. This is the single seam where the domain vocabulary meets HTTP, and it is the reason the domain can stay HTTP-free. See Responders.