3.3. Aura.Payload

You use a Payload as a data transfer object to send domain-layer results to your user-interface layer, along with meta-data indicating the meaning of the domain results.

3.3.1. Getting Started

Instantiating a Payload object is straighforward:

<?php
use Aura\Payload\Payload;

$payload = new Payload();
?>

You can then set the payload status and domain output, along with error codes, error messages, the input as received by the domain layer, and any extras you like.

While this may suffice for your particular implementation, there is also a factory object to allow each call to return its own payload.

<?php
use Aura\Payload\PayloadFactory;

$payloadFactory = new PayloadFactory();
$payload = $payloadFactory->newInstance();
?>

3.3.2. Methods

Use these methods in your domain layer to modify the Payload. (All set*() methods return the Payload object itself, so you can chain the methods fluently.)

Your calling code can then examine the payload object using the get*() complements to the the set*() methods.

3.3.3. Status Values

Several generic status values are available as constants on the Aura\Payload_Interface\PayloadStatus class:

You should consider creating your own domain-specific payload statuses as well.

Your user-interface layer can use these to determine how to process and present the domain objects retrieved via Payload::getOutput().

3.3.4. Example

Here is a naive example Application Service class that uses a Payload to return its results. Note how:

Any raised Exception gets transformed into an ERROR payload, with the exception and the input that led to the problem.

When your user-interface code receives the Payload, it can examine the payload status to discover exactly what happened in the domain layer, then determine how to present the information from the domain.

<?php
namespace App\Blog;

use Aura\Payload\PayloadFactory;
use Aura\Payload_Interface\PayloadStatus;
use Exception;

class ApplicationService
{
    protected $user;
    protected $mapper;
    protected $filter;
    protected $payloadFactory;

    public function __construct(
        User $user,
        BlogMapper $mapper,
        BlogFilter $filter,
        PayloadFactory $payloadFactory
    ) {
        $this->user = $user;
        $this->mapper = $mapper;
        $this->filter = $filter;
        $this->payloadFactory = $payloadFactory;
    }

    public function browsePosts($page = 1, $perPage = 10)
    {
        $payload = $this->payloadFactory->newInstance();

        try {

            $posts = $this->mapper->fetchAllByPage($page, $perPage);
            if (! $posts) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_FOUND)
                    ->setInput(func_get_args());
            }

            return $payload
                ->setStatus(PayloadStatus::FOUND)
                ->setOutput($posts);

        } catch (Exception $e) {
            return $this->error($e, func_get_args());
        }
    }

    public function readPost($id)
    {
        $payload = $this->payloadFactory->newInstance();

        try {

            $post = $this->mapper->fetchOneById($id);
            if (! $post) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_FOUND)
                    ->setInput(func_get_args());
            }

            return $payload
                ->setStatus(PayloadStatus::FOUND)
                ->setOutput($post);

        } catch (Exception $e) {
            return $this->error($e, func_get_args());
        }
    }

    public function editPost($id, array $input)
    {
        $payload = $this->payloadFactory->newInstance();

        try {

            $post = $this->mapper->fetchOneById($id);
            if (! $post) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_FOUND)
                    ->setInput(func_get_args());
            }

            if (! $post->isOwnedBy($user)) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_AUTHORIZED)
                    ->setInput(func_get_args());
            }

            $post->setData($input);
            if (! $this->filter->forUpdate($post)) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_VALID)
                    ->setInput($input)
                    ->setOutput($post)
                    ->setMessages($this->filter->getMessages());
            }

            $this->mapper->update($post);
            return $payload
                ->setStatus(PayloadStatus::UPDATED)
                ->setOutput($post);

        } catch (Exception $e) {
            return $this->error($e, func_get_args());
        }
    }

    public function addPost(array $input)
    {
        $payload = $this->payloadFactory->newInstance();

        try {

            $post = $this->mapper->newPost($input);
            if (! $this->filter->forInsert($post)) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_VALID)
                    ->setInput($input)
                    ->setOutput($post)
                    ->setMessages($this->filter->getMessages());
            }

            $this->mapper->create($post);
            return $payload
                ->setStatus(PayloadStatus::CREATED)
                ->setOutput($post);

        } catch (Exception $e) {
            return $this->error($e, func_get_args());
        }
    }

    public function deletePost($id)
    {
        $payload = $this->payloadFactory->newInstance();

        try {

            $post = $this->mapper->fetchOneById($id);
            if (! $post) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_FOUND)
                    ->setInput(func_get_args());
            }

            if (! $post->isOwnedBy($user)) {
                return $payload
                    ->setStatus(PayloadStatus::NOT_AUTHORIZED)
                    ->setInput(func_get_args());
            }

            $this->mapper->delete($post);
            return $payload
                ->setStatus(PayloadStatus::DELETED)
                ->setOutput($post);

        } catch (Exception $e) {
            return $this->error($e, func_get_args());
        }
    }

    protected function error(Exception $e, array $args)
    {
        $payload = $this->payloadFactory->newInstance();
        return $payload
            ->setStatus(PayloadStatus::ERROR)
            ->setInput($args)
            ->setOutput($e);
    }
}
?>