#league/fractal
WRAPPER FOR LARAVEL 5/LUMEN#
#INDEX
- ABOUT
- GOAL OF THIS PACKAGE
- LARAVEL/LUMEN IMPLEMENTATION EXAMPLE
- HOW TO INSTALL
- BUNDLED EXAMPLE
- AVAILABLE RESPONSE METHOD
This is a package, or rather an opinionated/laravelish use case of the famous league/fractal
package for Laravel 5 and Lumen. This package was started to fulfill a personal RESTful API service needs. And provided as a separate package, hoping users quickly build his/her RESTful API.
Among 1. METHOD, 2. RESOURCE, and 3. RESPONSE, which is 3 pillars of REST, this package is mainly focusing on a 3. RESPONSE(=view layer). By reading this readme and following along the bundled examples, I hope you understand REST principles, and build a beautiful APIs that everybody can understand easily.
I know RESTful API is a big topic. Note that REST is not a strict spec or rule, but just a guideline. The more RESTful, the easier to be read by your API consumers.
- Provides easy access to the
league/fractal
's core instance (ServiceProvider). - Provides easy way of make transformed/serialized http response.
- Provides configuration capability for the response format.
- Provides examples, so that users can quickly copy & paste into his/her project.
##LARAVEL/LUMEN IMPLEMENTATION EXAMPLE
1. METHOD and 2. RESOURCE can be easily handled by Laravel/Lumen routes file, app/Http/routes.php
.
Route::resource(
'things',
ThingsController::class,
['except' => ['create', 'edit']]
);
In response to Laravel/Lumen route definition, Appkr\Fractal\Http\Response
instance is being injected into ThingsController
to properly format JSON responses in RESTful fashion (3. RESPONSE).
<?php
namespace App\Http\Controllers\V1;
use App\Http\Controllers\Controller;
use App\Http\Requests\ThingsRequest;
use App\Thing;
use App\Transformers\ThingTransformer;
use Appkr\Fractal\Http\Response;
class ThingsController extends Controller
{
protected $response;
public function __construct(Response $response)
{
$this->response = $response;
}
public function index()
{
return $this->response->withPagination(
Thing::latest()->paginate(25),
new ThingTransformer
);
}
public function store(ThingsRequest $request)
{
return $this->response->created(Thing::create(array_merge(
$request->all(),
$request->user()->id
)));
}
public function show($id)
{
return $this->response->withItem(
Thing::findOrFail($id),
new ThingTransformer
);
}
public function update(ThingsRequest $request, $id)
{
$thing = Thing::findOrFail($id);
return ($thing->update($request->all()))
? $this->response->success('Updated')
: $this->response->error('Fail to update');
}
public function destroy($id)
{
$thing = Thing::findOrFail($id);
return ($thing->delete())
? $this->response->success('Deleted')
: $this->response->error('Fail to delete');
}
}
Setp #1: Composer.
$ composer require "appkr/fractal: 0.6.*"
Step #2: Add the service provider.
// For Laravel - config/app.php
'providers'=> [
Appkr\Fractal\ApiServiceProvider::class,
]
// For Lumen - boostrap/app.php
$app->register(Appkr\Fractal\ApiServiceProvider::class);
Step #3: [OPTIONAL] Publish assets.
// For Laravel only
$ php artisan vendor:publish --provider="Appkr\Fractal\ApiServiceProvider"
The config file is located at config/fractal.php
.
Done !
The package is bundled with a simple API example. It includes:
- Database migrations and seeder
- routes definition, Eloquent Model and corresponding Controller
- FormRequest (Laravel only)
- Transformer
- Integration Test
Follow the guide to activate and test the example.
Step #1: Activate examples
// Uncomment the line at vendor/appkr/fractal/src/ApiServiceProvider.php
$this->publishExamples();
Step #2: Migrate and seed tables
// Migrate/seed tables at a console
$ php artisan migrate --path="vendor/appkr/fractal/database/migrations"
$ php artisan db:seed --class="Appkr\Fractal\Example\DatabaseSeeder"
Step #3: Boot up a local server and open at a browser
// Boot up a local server
$ php artisan serve
Head on to http://localhost:8000/v1/things
, and you should see a well formatted json response.
Step #4: [OPTIONAL] Run integration test
// For Laravel
$ phpunit vendor/appkr/fractal/src/example/ThingApiTestForLaravel.php
// For Lumen
$ phpunit vendor/appkr/fractal/src/example/ThingApiTestForLumen.php
Note
If you finished evaluating the example, don't forget to rollback the migration and re-comment the unnecessary lines at ApiServiceProvider
.
The following is the full list of response methods that Appkr\Fractal\Http\Response
provides, and that you can use in YourController
to format API response.
// Generic response.
// If valid callback parameter is provided, jsonp response can be provided.
// This is a very base method. All other responses are utilizing this.
respond(array $payload);
// Respond collection of resources
// If $transformer is not given as the second argument,
// this class does its best to transform the payload to a simple array
withCollection(
\Illuminate\Database\Eloquent\Collection $collection,
\League\Fractal\TransformerAbstract|null $transformer,
string|null $resourceKey // for JsonApiSerializer only
);
// Respond single item
withItem(
\Illuminate\Database\Eloquent\Model $model,
\League\Fractal\TransformerAbstract|null $transformer,
string|null $resourceKey // for JsonApiSerializer only
);
// Respond collection of resources with pagination
withPagination(
\Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator,
\League\Fractal\TransformerAbstract|null $transformer,
string|null $resourceKey // for JsonApiSerializer only
);
// Respond json formatted success message
// fractal.php provides configuration capability
success(string|array $message);
// Respond 201
// If an Eloquent model is given at an argument,
// the class tries its best to transform the model to a simple array
created(string|array|\Illuminate\Database\Eloquent\Model $primitive);
// Respond 204
noContent();
// Generic error response
// This is another base method. Every other error responses use this.
// If an instance of \Exception is given as an argument,
// this class does its best to properly format a message and status code
error(string|array|\Exception|null $message);
// Respond 401
// Note that this actually means unauthenticated
unauthorizedError(string|array|null $message);
// Respond 403
// Note that this actually means unauthorized
forbiddenError(string|array|null $message);
// Respond 404
notFoundError(string|array|null $message);
// Respond 406
notAcceptableError(string|array|null $message);
// Respond 409
conflictError(string|array|null $message);
// Respond 422
unprocessableError(string|array|null $message);
// Respond 500
internalError(string|array|null $message);
// Set http status code
// This method is chainable
setStatusCode(int $statusCode);
// Set http response header
// This method is chainable
setHeaders(array $headers);
// Set additional meta data
// This method is chainable
setMeta(array $meta);
####AVAILABLE HELPER METHODS
// Determine if the current framework is Laravel
is_laravel();
// Determine if the current framework is Lumen
is_lumen();
// Determine if the current version of framework is based on 5.1
is_51();
// Determine if the current request is generated from an api client
is_api_request();
// Determine if the request is for update
is_update_request();
// Determine if the request is for delete
is_delete_request();
##LICENSE & CONTRIBUTION
This package follows MIT License. Issues and PRs are welcomed.