perfect-oblivion/responders

Responder Implementation for Laravel Projects

0.3.0 2019-10-17 20:30 UTC

This package is auto-updated.

Last update: 2022-05-18 01:57:36 UTC


README

A Responder Implementation for Laravel Projects.

Latest Stable Version Build Status Quality Score Total Downloads

Perfect Oblivion

Disclaimer

The packages under the PerfectOblivion namespace exist to provide some basic functionality that I prefer not to replicate from scratch in every project. Nothing groundbreaking here.

Responders are a great way to make your controllers slim and keep the code related to responses in one place. The general idea is based on the "R" in ADR - Action Domain Responder, by Paul M. Jones.

For example, in your controller:

namespace App\Http\Controllers;

use App\MyDatasource;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Responders\Post\IndexResponder;

class PostIndex implements Controller
{
    /**
     * The Responder.
     *
     * @var \App\Http\Responders\Post\IndexResponder
     */
    private $responder;

    /**
     * Construct a new PostIndex Controller.
     *
     * @param \App\Http\Responders\Post\IndexResponder $responder
     */
    public function __construct(Responder $responder)
    {
        $this->responder = $responder;
    }

    public function index(Request $request)
    {
        $data = MyDatasource::getSomeData($request);

        return $this->responder->withPayload($data);
    }
}

Then in your responder:

namespace App\Http\Responders\Post;

use PerfectOblivion\Responder\Responder;

class IndexResponder extends Responder
{
    /**
     * Send a response.
     *
     * @return mixed
     */
    public function respond()
    {
        if (request()->isApi()) { // isApi() is not part of this package
            // return json
        }

        return $this->view('posts.index', ['posts' => $this->payload]);
    }
}

The benefit over the traditional "handle the response inside your controller actions", is the clarity it brings, the narrow class responsibility, fewer dependencies in your controller and overall organization. When used together with single action controllers, you can really clean up your controllers and bring a lot of clarity to your codebase.

Installation

You can install the package via composer:

composer require perfect-oblivion/responders

Laravel versions > 5.6.0 will automatically identify and register the service provider.

If you are using an older version of Laravel, add the package service provider to your config/app.php file, in the 'providers' array:

'providers' => [
    //...
    PerfectOblivion\Services\ResponderServiceProvider::class,
    //...
];

Then, run:

php artisan vendor:publish

and choose the PerfectOblivion/Responders option.

This will copy the package configuration (responders.php) to your 'config' folder. Here, you can set the root namespace for your Responder classes:

return [

    /*
    |--------------------------------------------------------------------------
    | Namespace
    |--------------------------------------------------------------------------
    |
    | Set the namespace for the Responders.
    |
 */

    'namespace' => 'Http\\Responders'
];

Usage

To begin using PerfectOblivion/Responders, simply follow the instructions above, then generate your Responder classes as needed. To generate an IndexResponder for Posts, as in the example above, enter the following command into your terminal:

php artisan adr:responder Post\\IndexResponder

Then add the responder as a dependency to your controller. Simply return the responder in your action. If you have data to pass to the responder, call the withPayload() method and pass the data:

public function index(Request $request)
{
    $data = MyDatasource::getSomeData();

    // return $this->responder;
    return $this->responder->withPayload($data);
}

Note: Responders implement the Laravel's Responsable interface. From your controllers/actions if you return the responder object, the respond() method of your responder, will automatically be called. If you're in a situation where you are returning an object the implements Responsable from your respond() method, you'll need to explicitly call the respond() method from your controller or action. For example, using the inertiajs/inertia-laravel package, the Inertia::render method gives you a responsable object. If you're returning Inertia::render from your responder, you need to explicitly call the respond() method of your responder from your controller or action. See the example code below.

// MyController.php
public function index(Request $request)
{
    $data = MyDatasource::getSomeData();

    // return $this->responder->respond();
    return $this->responder->withPayload($data)->respond();
}
namespace App\Http\Responders\Post;

use Inertia\Inertia;
use PerfectOblivion\Responder\Responder;

class IndexResponder extends Responder
{
    /**
     * Send a response.
     *
     * @return mixed
     */
    public function respond()
    {
        return Inertia::render('Posts/Index', ['posts' => $this->payload]);
    }
}

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email clay@phpstage.com instead of using the issue tracker.

Roadmap

We plan to work on flexibility/configuration soon, as well as release a framework agnostic version of the package.

Credits

License

The MIT License (MIT). Please see License File for more information.