-
-
Save ultimateprogramer/bcbcdfcd8c57d0981300d47fb0239a5a to your computer and use it in GitHub Desktop.
An laravel's style implementation of API handler.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/************************************************* | |
* API base controller for laravel | |
*************************************************/ | |
class ApiController extends Controller { | |
/** | |
* Create a json Response including errors and no data | |
* @param array $errors the errors | |
* @return responce The responce including error data | |
*/ | |
private function jsonError(array $errors) | |
{ | |
return $this->jsonReply(array(), $errors); | |
} | |
/** | |
* Create a json Response, including data and errors | |
* @param array $data The data | |
* @param array $errors The errors | |
* @return Responce The responce containing json encoded data | |
*/ | |
private function jsonReply(array $data, array $errors = array()) | |
{ | |
if(!empty($errors)) | |
{ | |
//Crée le contenant | |
if(!isset($data['errors'])) | |
{ | |
$data['errors'] = new MessageBag(); | |
} | |
if(!($data['errors'] instanceof MessageBag)) | |
{ | |
throw new Exception('errors element in json must be a MessageBag instance'); | |
} | |
//ajoute les erreurs au contenant actuel | |
if ($errors instanceof MessageProviderInterface) | |
{ | |
$data['errors']->merge($errors->getMessageBag()->toArray()); | |
} | |
else | |
{ | |
$data['errors']->merge((array) $errors); | |
} | |
//converti en array pour le transfert en json si la collection n'est pas vide, détruit sinon | |
if($data['errors']->any()) | |
$data['errors'] = $data['errors']->toArray(); | |
else | |
unset($data['errors']); | |
//erreur, defini le success a false | |
$data['success'] = false; | |
} | |
//retourne la reponse contenant les données et le json | |
return Response::json($data); | |
} | |
/** | |
* Execute the passed function then return the result (or exceptions) as json | |
* @param Closure $f The function to execute | |
* @return string data as json encoded string | |
*/ | |
public function apiOutput(Closure $f) | |
{ | |
try | |
{ | |
$default['success'] = true; | |
$return = $f(); | |
$return = array_merge($default, (array) $return); | |
return $this->jsonReply($return); | |
} | |
catch (AppException $e) | |
{ | |
$return['exception'] = $e->getMessage(); | |
return $this->jsonError($return); | |
} | |
catch (Exception $e) | |
{ | |
$return['exception'] = $e->getMessage(); | |
Log::error($e->__toString()); | |
return $this->jsonError($return); | |
} | |
} | |
} | |
/************************************************* | |
* Usage example (API side) | |
*************************************************/ | |
class TestAPI extends ApiController { | |
function index() | |
{ | |
return $this->apiOutput(function(){ | |
if(!Auth::check()) | |
{ | |
//exceptions are returned in JSON in the form : | |
//{success:false, exception: "Exception message"} | |
throw new AppException('errors.mustlogin'); | |
} | |
//prepare some random data | |
$view_data = array(); | |
$view_data['var1'] = 17; | |
$view_data['var2'] = "SomeTest"; | |
$view_data['var3'] = Auth::user()->toArray(); | |
//the view data is translated into json form | |
//Resulting output is in the form: | |
//{success:true, var1:17, var2:"SomeTest", var3:{UserAsJson}} | |
return $view_data; | |
}); | |
} | |
} | |
/************************************************* | |
* Non API base controller for laravel | |
*************************************************/ | |
class BaseController extends Controller { | |
/** | |
* Call an internal api url | |
* | |
* @return \StdClass response | |
*/ | |
protected function callApi($url, $method = 'GET', $input = null) | |
{ | |
Profiler::startTimer('Api call to '.$url); | |
if(is_null($input)) | |
{ | |
$input = Request::input(); | |
} | |
//save original input | |
$originalInput = Request::input(); | |
Request::replace($input); | |
//dispatch the request, then parse the responce | |
$request = Request::create($url, $method); | |
$responce = json_decode(Route::dispatch($request)->getContent()); | |
//get error array from JSON (if any) | |
if(isset($responce->errors) && !empty($responce->errors)) | |
{ | |
$data = App::make('view')->getShared(); | |
if(isset($data['errors'])) | |
{ | |
$data['errors']->merge((array) $responce->errors); | |
} | |
else | |
{ | |
$data['errors'] = new MessageBag((array) $responce->errors); | |
} | |
App::make('view')->share('errors', $data['errors']); | |
} | |
//Replace original input | |
Request::replace($originalInput); | |
Profiler::endTimer('Api call to '.$url); | |
return $responce; | |
} | |
} | |
/************************************************* | |
* Non API controller (frontend) Usage example | |
*************************************************/ | |
class TestFrontend extends BaseController { | |
public function index() | |
{ | |
//just in case? | |
if(!Auth::check()) | |
{ | |
return Redirect::to(action('Home@index')); | |
} | |
$view_data = array(); | |
$responce = $this->callApi('/api/test'); | |
if ($view_data['success'] == 1) | |
{ | |
$view_data['var1'] = $responce->var1; | |
$view_data['var2'] = $responce->var2; | |
$view_data['var3'] = $responce->var3; | |
return View::make('testapi', $view_data); | |
} | |
else | |
{ | |
//Display error using message in $responce['exception'] | |
return View::make('errorpage', $responce); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment