dev-master
9999999-devA simple Laravel API package.
MIT
The Requires
- php >=5.4.0
- league/fractal 0.9.*
- laravel/framework 4.2.*
by Rati Wannapanop
A simple Laravel API package.
A simple Laravel based API package using Fractal. At the moment, Laravel 5 is not yet officially released, so this package was based on Laravel 4.2., (*1)
This package simplify the API request building and transforming using The PHP Leagues's Fractal
as the underlying engine., (*2)
To use it, you just need to follow these 3 steps, (*3)
Ratiw\Api\BaseApiController
class.Ratiw\Api\BaseTransformer
class.Installation can be done via composer
, (*4)
"require": { "ratiw/api": "dev-master" }
This package requires Laravel Framework
v4.2 and Fractal
v0.9.*, so it will be pull in automatically, (*5)
Api
directory.composer.json
like so... "autoload": { "psr-4": { "Api\\": "app/Api", "Entities\\": "app/Entities" } } ...
Api\Controllers
directory.Api\Transformers
directory.Client
eloquent based class exists in the `Entities\Clients' directory.<?php namespace Entities\Clients; class Client extends \Eloquent { protected $table = 'clients'; public function saleRep() { return $this->belongsTo('Entities\Staffs\Sale', 'sale_id'); } }
<?php namespace Api\Controllers; use Ratiw\Api\BaseApiController; class ClientsController extends BaseApiController { protected $model = 'Entities\Clients\Client'; }
This is optional though. You don't need to create a Transformer if you don't want to transform any field., (*6)
<?php namespace Api\Transformers; use Ratiw\Api\BaseTransformer; class ClientTransformer extends BaseTransformer { public function transform($client) { return [ 'id' => (int) $client->id, 'short_name' => $client->shortname, 'full_name' => $client->name, 'sale_id' => $client->sale_id, 'contact' => $client->contact, 'email' => $client->email, 'phone' => $client->phone ]; } }
Route::group(['prefix' => 'api'], function() { Route::get('clients/{id}', 'Api\Controllers\ClientsController@show'); Route::get('clients', 'Api\Controllers\ClientsController@index'); ... }
By default, the API package comes ready with two methods - index() for querying the collection - show() for querying specific item, (*7)
You should be able to test it via your browser. Just go to http://localhost
or http://localhost:8000
or whatever appropriate in your development environment. However, if you've setup your environment different than that, you will have to create a configuration file for that., (*8)
Note: If you use Google Chrome browser, you can install JSONView from Chrome Web Store to help prettify the JSON result., (*9)
The API class, by default, will first check to see if the calling party is from the allowable host or domain. If it is originate from the domain other than the ones configured, it will return an error., (*10)
By default, the allowable hosts are: - localhost - localhost:8000, (*11)
In order to change this or add more hosts, you will need to create a configuration file in the app/config
directory like so,, (*12)
// app/config/api.php <?php return [ 'allow_hosts' => [ 'localhost:8000', 'localhost' 'myawesome.app:8000', //<-- your addition allowable domain ], 'allow_paths' => [ 'api/*' ] ];
Sort operation can be done by passing sort
parameter in the query string when calling the Api controller., (*13)
http://localhost:8000/clients?sort=shortname
To sort in descending order, just prepend the sort column with -
, (*14)
http://localhost:8000/clients?sort=-shortname
The results can be filtered by specifying the the q
parameter in the query string., (*15)
http://localhost:8000/clients?q=John
By default, it will perform where
clause on the field named code
, which will cause error if your model does not have code
field.
You can fix this by overriding the search()
method, like so., (*16)
... protected function search($query, $q) { return $query->where('shortname', 'like', "%$q%") ->orWhere('name', 'like', '%$q%'); } ...
If you want to always apply specific conditions to the query result, you can do so by overriding getDefaultFilters
function.
The query builder
object will be passed to this function and you can apply any condition you want., (*17)
class ClientsController extends BaseApiController { ... public function getDefaultFilters($query) { return $query->where('sale_id', Auth::id()); } ... }
The returned or transformed result is paginated by default to 10 records. To change this, just pass per_page
parameter on the query string., (*18)
http://localhost:8000/clients?per_page=20
You can limit the fields to be returned by supplying the fields
parameter on the query string, like so., (*19)
http://localhost:8000/clients?fields=id,name
To eager load the result of the query, just specifying it in the $eagerLoads
array property of the Api class., (*20)
... class ClientsController extends BaseApiController { $protected $eagerLoads = ['saleRep']; ... }
API package will automatically looks for a corresponding Transformer class using the following criteria:, (*21)
$transformer
property. If the Transformer does not exist, exception will be thrown.$model
property to guess the Transformer class. If the Transformer class does not exist, the Ratiw\Api\BaseTransformer
class will be used.This provides enough ease and flexibility. If your project is small and not so complicated, you can just put the Api classes and Transformer classes in the same directory. Or, you won't even have to define any Transformer for the Api class if you do not need to transform anything., (*22)
But if your project is quite complex or you prefer putting things in directory where you can organized things neatly, you have the flexibility to do so by specifying the $transformer
class to use in the Api class., (*23)
... class ClientsController extends BaseApiController { protected $model = 'Entities\Clients\Client'; protected $transformer = 'Api\Transformers\ClientTransformer'; ... } ...
By default, the Api class will look for its associated Transformer class in the same directory, but you can override this by putting the transformer_path
in the app/config/api.php
file., (*24)
<?php return [ 'allowable_path' => [...]; ... 'transformer_path' => 'Api\\Transfomers\\'; ];
Note the double backslash \\
in the path. Double backslash at the end is not required though., (*25)
Embbed resources (nested resources) can be included using the machanism defined by Fractal
., (*26)
... class ClientTransformer extends BaseTransformer { protected $defaultIncludes = ['saleRep']; public function transform($client) { ... } public function includeSaleRep($client) { $saleRep = $client->saleRep; return $this->item($saleRep, new SaleTransformer); } }
A simple Laravel API package.
MIT