!!! Project abandoned. See cloudcreativity/laravel-json-api for a great alternative.
Make it a breeze to create a jsonapi.org compliant API with Laravel 5.
This library strives to be up to date with the latest JSON API updates—as the spec is still a work in progress. If you notice that something is missing, please contribute!
Add echo-it/laravel-jsonapi
to your composer.json dependency list (version 2.0.0 at the minimum for laravel 5 support)
Run composer update
.
This library is made with the concept of exposing models in mind, as found in the RESTful API approach.
In few steps you can expose your models:
Create a route to direct the requests
In this example, we use a generic route for all models and HTTP methods:
Route::any('{model}/{id?}', 'ApiController@handleRequest');
Create your controller to handle the request
Your controller is responsible to handling input, instantiating a handler class and returning the response.
<?php namespace App\Http\Controllers;
use EchoIt\JsonApi\Request as ApiRequest; use EchoIt\JsonApi\ErrorResponse as ApiErrorResponse; use EchoIt\JsonApi\Exception as ApiException; use Request;
class ApiController extends Controller { public function handleRequest($modelName, $id = null) { /**
@var string */ $handlerClass = 'App\Handlers\' . ucfirst($modelName) . 'Handler';
if (class_exists($handlerClass)) {
$url = Request::url();
$method = Request::method();
$include = ($i = Request::input('include')) ? explode(',', $i) : $i;
$sort = ($i = Request::input('sort')) ? explode(',', $i) : $i;
$filter = ($i = Request::except('sort', 'include', 'page')) ? $i : [];
$content = Request::getContent();
$page = Request::input('page');
$pageSize = null;
$pageNumber = null;
if($page) {
if(is_array($page) && !empty($page['size']) && !empty($page['number'])) {
$pageSize = $page['size'];
$pageNumber = $page['number'];
} else {
return new ApiErrorResponse(400, 400, 'Expected page[size] and page[number]');
}
}
$request = new ApiRequest(Request::url(), $method, $id, $content, $include, $sort, $filter, $pageNumber, $pageSize);
$handler = new $handlerClass($request);
// A handler can throw EchoIt\JsonApi\Exception which must be gracefully handled to give proper response
try {
$res = $handler->fulfillRequest();
} catch (ApiException $e) {
return $e->response();
}
return $res->toJsonResponse();
}
// If a handler class does not exist for requested model, it is not considered to be exposed in the API
return new ApiErrorResponse(404, 404, 'Entity not found');
} }
Create a handler for your model
A handler is responsible for exposing a single model.
In this example we have create a handler which supports the following requests:
Requests are automatically routed to appropriate handle functions.
<?php namespace App\Handlers;
use Symfony\Component\HttpFoundation\Response; use App\Models\User;
use EchoIt\JsonApi\Exception as ApiException; use EchoIt\JsonApi\Request as ApiRequest; use EchoIt\JsonApi\Handler as ApiHandler; use Request;
/**
Handles API requests for Users. */ class UsersHandler extends ApiHandler { const ERROR_SCOPE = 1024;
/*
/**
/**
Note: Extend your models from
EchoIt\JsonApi\Model
rather thanEloquent
to get the proper response for linked resources.
According to jsonapi.org:
The features in the Handler class are each in their own function (eg. handlePaginationRequest, handleSortRequest, etc.), so you can easily override them with your own behaviour if desired.
Nested requests to fetch relations, e.g. /users/[id]/friends
Requests for multiple individual resources, e.g. /users/1,2,3
Some kind of caching mechanism