Laravel Example - daison12006013/blaze-code GitHub Wiki

Route

# config/routes.php

return [
    [
        'prefix' => ['v1', 'v1.0'],
        'with_suffix' => true,
        'middleware' => ['auth:api'],
        'namespace' => 'App\\Http\\Controllers\\V1',
        'routes' => [
            'books',
        ],
    ],
];

In your routes/api.php,

$factory = new BlazeCode\RouteFactory(config('routes'));
$factory->register(new BlazeCode\Laravel\Route(), __DIR__.'/api');

The above code registers the lists of routes, you need to create a file routes/api/v1/books.php, and copy below code

Route::get('/', 'BookController@listsAction')->name('v1.books.lists');

Since the config above has with_suffix that is equal to true, we're telling Blaze to apply the route lists as suffix itself, e.g (http://local.app/v1/books)

Request Handler

Add these methods to your App\Http\Controllers\V1\Controller.php

/**
 * Process methods.
 *
 * @param \Closure $before
 * @param string $transformer
 * @return mixed
 */
protected function methodHandler($before, $transformer = null)
{
    # we only want to response as json.
    # modify below if you want to respond a different way.
    $after = function ($response) {
        return response()->json($response, $response['code']);
    };

    # we need to set our own serializer, so we could omit the 'data' key in the fractal transformation.
    # let's call the parseIncludes() too to handle optimization.
    $manager = function ($fractal) {
        $fractal->setSerializer(new \BlazeCode\Utils\NoDataKeySerializer());

        $fractal->parseIncludes(
            request()->get('include', [])
        );
    };

    return $this->blaze()->handle([
        'requests' => [
            'before' => $before,
            'after'  => $after,
        ],
        'fractal' => [
            'transformer' => $transformer,
            'manager' => $manager,
        ],
    ]);
}

After adding above code, you may call it like this to your BookController.

    /**
     * Get lists of books.
     *
     * @return string
     */
    public function listsAction(\Illuminate\Http\Request $request)
    {
        return $this->methodHandler(
            BlazeCode\Helpers\repository(\App\Repositories\Book\Lists::class, [$request])
        );
    }

The above code will inject the repository class with the parameters we like to pass in, we need to create a class App\Repositories\Book\Lists and copy below code.

namespace App\Repositories\Book;

use App\Models;

class Lists
{
    public function handle($request)
    {
        $builder = (new Models\Book)->newQuery();

        // @todo filters

        return $builder->paginate(10);
    }
}

Try to vist the link to your local http://local.app/v1/books, it should show like this:

{
    success: true,
    code: 200,
    data: {
        current_page: 1,
        data: [],
        from: 1,
        last_page: 616,
        next_page_url: "http://local.app/v1/books?page=2",
        path: "http://local.app/v1/books",
        per_page: 10,
        prev_page_url: null,
        to: 10,
        total: 6159
    },
    metadata: {
        current_page: 1,
        from: 1,
        last_page: 616,
        next_page_url: "http://local.app/v1/books?page=2",
        path: "http://local.app/v1/books",
        per_page: 10,
        prev_page_url: null,
        to: 10,
        total: 6159
    },
    processing_time: 0.11623597145080566
}

Transformer

Are you familiar with http://fractal.thephpleague.com? Blaze can actually help you to auto format your data.

Modify your listsAction() in your BookController, it should look like this

    /**
     * Get lists of items.
     *
     * @return string
     */
    public function listsAction(\Illuminate\Http\Request $request)
    {
        return $this->methodHandler(
            BlazeCode\Helpers\repository(\App\Repositories\Book\Lists::class, [$request]),
            'Collection::App\Transformers\Book'
        );
    }

The above code, we're telling PHP League's Fractal to use the Collection since the data is more than one (1). By default, if you only pass App\Transformers\Book it will automatically use the Item of Fractal.

Examples Are:

  • Collection::Your\Transformers\Class\Here
  • Item::Your\Transformers\Class\Here
  • \Your\Transformers\Class\Here::class

Create the transformer App\Transformers\Book, the sample code must be like this

namespace App\Transformers;

use App\Models;
use League\Fractal;

class Book extends Fractal\TransformerAbstract
{
    /**
     * {@inherit}
     */
    public function transform(Models\Book $book)
    {
        $data = [
            'id' => $book->id,
            'name' => $book->name,
        ];

        if ($book->author) {
            $data['author'] = $book->author->name;
        }

        if ($sales_count = $book->sales()->count()) {
            $data['sales'] = $sales_count;
        }

        return $data;
    }
}

Visit your website and you should be able to see the transformed data.

{
    success: true,
    code: 200,
    data: {
        {
            'id': 1,
            'name': "Harry Potter and the Prisoner of Azkaban",
            'author': 'J.K. Rowling',
            'sales': 55081533
        }
        ...
    },
    metadata: {
        current_page: 1,
        from: 1,
        last_page: 616,
        next_page_url: "http://local.app/v1/books?page=2",
        path: "http://local.app/v1/books",
        per_page: 10,
        prev_page_url: null,
        to: 10,
        total: 6159
    },
    processing_time: 0.11623597145080566
}