SlideShare une entreprise Scribd logo
1  sur  40
Télécharger pour lire hors ligne
Bootstrap REST APIs
with Laravel 5
Elena Kolevska
www.speedtocontact.com
Automated lead response system / call center in a
browser
Why REST?
SOAP!
POST http://www.stgregorioschurchdc.org/cgi/websvccal.cgi HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://www.stgregorioschurchdc.org/Calendar#easter_date"
Content-Length: 479
Host: www.stgregorioschurchdc.org
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<?xml version="1.0"?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cal="http://www.stgregorioschurchdc.org/Calendar">
<soapenv:Header/>
<soapenv:Body>
<cal:easter_date soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/
encoding/">
<year xsi:type="xsd:short">2014</year>
</cal:easter_date>
</soapenv:Body>
</soapenv:Envelope>
Basic Authentication
ALWAYS use SSL!
$header = 'Authorization: Basic' . base64_encode($username . ':' . $password);
Authentication Middleware
<?php namespace AppHttpMiddleware;
use AppUser;
use Closure;
use IlluminateContractsAuthGuard;
use IlluminateSupportFacadesHash;
class AuthenticateOnce {
public function handle($request, Closure $next)
{
if ($this->auth->onceBasic())
return response(['status'=>false, 'message'=>'Unauthorized'], 401, ['WWW-Authenticate' =>'Basic']);
return $next($request);
}
protected $routeMiddleware = [
'auth' => 'AppHttpMiddlewareAuthenticate',
'auth.basic' => 'IlluminateAuthMiddlewareAuthenticateWithBasicAuth',
'auth.basic.once' => 'AppHttpMiddlewareAuthenticateOnce',
'guest' => 'AppHttpMiddlewareRedirectIfAuthenticated',
];
<?php
Route::group(array('prefix' => 'api/v1/examples','middleware' => 'auth.basic.once'), function () {
Route::get('1', 'ExamplesController@example1');
Route::get('2', 'ExamplesController@example2');
Route::get('3', 'ExamplesController@example3');
Route::get('4', 'ExamplesController@example4');
Route::get('5', 'ExamplesController@example5');
Route::get('6', 'ExamplesController@example6');
Route::get('7', 'ExamplesController@example7');
Route::get('8', 'ExamplesController@example8');
});
app/Http/routes.php
Response format
HTTP/1.1 200 OK
Content-Type: application/json 

Connection: close 

X-Powered-By: PHP/5.6.3

Cache-Control: no-cache

Date: Fri, 13 Apr 2015 16:37:57 GMT 

Transfer-Encoding: Identity

{"status":true,"data":{"k1":"value1","k2":"value2"},"message":"Zero imagination for funny
messages"}
Most common HTTP status codes
• 200 OK
• 201 Created
• 204 No Content
• 400 Bad Request
• 401 Unauthorized
• 403 Forbidden
• 404 Not Found
• 409 Conflict
• 500 Internal Server Error
Response message format
{
"status": true,
"data": {
"k1": "value1",
"k2": "value2"
},
"message": "Zero imagination for funny messages"
}
{
"status": false,
"errors": {
"e1": "Nope, it can't be done",
"e2": "That can't be done either"
},
"error_code": 12345,
"message": "Zero imagination for funny messages"
}
Controller hierarchy
app/Http/Controllers/ApiController.php
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use IlluminateRoutingResponseFactory;
use IlluminateAuthGuard;
use AppUser;
class ApiController extends Controller{
public $response;
public $request;
public $auth;
public function __construct(ResponseFactory $response, Request $request, Guard $auth)
{
$this->response = $response;
$this->request = $request;
$this->auth = $auth;
$this->currentUser = $this->auth->user();
}
}
app/Http/Controllers/ApiController.php
public function respond($data, $response_message, $status_code = 200) {
//If this is an internal request we only return the data
if ($this->request->input('no-json'))
return $data;
$message['status'] = true;
if (isset($data))
$message['data'] = $data;
if (isset($message))
$message['message'] = $response_message;
if (isset($error_code))
$message['error_code'] = $error_code;
return $this->response->json($message, $status_code);
}
app/Http/Controllers/ExamplesController.php
<?php namespace AppHttpControllers;
class ExamplesController extends ApiController {
/**
* Send back response with data
*
* @return Response
*/
public function example1()
{
$sample_data_array = ['k1'=>'value1', 'k2'=>'value2'];
return $this->respond($sample_data_array, 'Message');
}
}
app/Http/Controllers/ApiController.php
public function respondWithError($errors, $error_code, $status_code = 400) {
if (is_string($errors))
$errors = [$errors];
$message = [
'status' => false,
'errors' => $errors,
'error_code' => $error_code
];
return $this->response->json($message, $status_code);
}}
public function example3()
{
$error = "Can't be done";
return $this->respondWithError($error, 123, 500);
}
app/Http/Controllers/ExamplesController.php
app/Http/Controllers/ApiController.php
}
/**
* @param array $errors
* @param int $status_code
* @return Response
*/
public function respondWithValidationErrors($errors, $status_code = 400) {
$message = [
'status' => false,
'message' => "Please double check your form",
'validation_errors' => [$errors]
];
return $this->response->json($message, $status_code);
}
}
app/Http/Controllers/ApiController.php
public function respondCreated( $message = 'Resource created') {
return $this->respond($message, 201);
}
public function respondUnauthorized( $error_code, $message = 'You are not authorized for this') {
return $this->respondWithError($message, $error_code, 401);
}
public function respondNotFound( $error_code, $message = 'Resource not found') {
return $this->respondWithError($message, $error_code, 404);
}
public function respondInternalError( $error_code, $message = 'Internal error') {
return $this->respondWithError($message, $error_code, 500);
}
public function respondOk( $message = 'Done') {
return $this->respond(null, $message, 200);
}
Always use fake data
for testing
https://github.com/fzaninotto/Faker
<?php
use IlluminateDatabaseSeeder;
class UsersTableSeeder extends Seeder {
public function run()
{
Eloquent::unguard();
$faker = FakerFactory::create();
for($i=1; $i < 20; $i++ ){
$data = [
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt('demodemo')
];
AppUser::create($data);
}
}
}
database/seeds/UsersTableSeeder.php
Setting up the repositories
app/Providers/RepoBindingServiceProvider.php
<?php
namespace AppProviders;
use IlluminateSupportServiceProvider;
class RepoBindingServiceProvider extends ServiceProvider {
public function register() {
$app = $this->app;
$app->bind('AppRepositoriesContractsUsersInterface', function()
{
$repository = new AppRepositoriesUsersRepository(new AppUser);
return $repository;
});
}
}
* Register the service provider in the list of autoloaded service providers in config/app.php
app/Repositories/BaseRepository.php
<?php
namespace AppRepositories;
use IlluminateDatabaseEloquentModel;
class BaseRepository {
public function __construct(Model $model) {
$this->model = $model;
}
public function create($data)
{
return $this->model->create($data);
}
public function find($id)
{
return $this->model->find($id);
}
public function delete($id)
{
return $this->model->destroy($id);
}
public function all()
{
return $this->model->all();
}
app/Repositories/BaseRepository.php
public function update($record, $data)
{
if (is_int($record)){
$this->model->find($record);
$id = $record;
} else {
$this->model = $record;
$id = $record->id;
}
return $this->model->where('id',$id)->update($data);
}
public function getById($id, $user_id = null, $with = null)
{
if (is_array($id)){
$result = $this->model->whereIn('id', $id);
}else{
$result = $this->model->where('id', $id);
}
if ($user_id)
$result->where('user_id', $user_id);
if ($with)
$result->with($with);
if (is_array($id)){
return $result->get();
return $result->first();
}
public function example5()
{
$data = App::make('AppRepositoriesContractsUsersInterface')->getById(3,null,['courses']);
return $this->respond($data,"All users");
}
{
"status": true,
"data": {
"id": 3,
"name": "Asia Towne DVM",
"email": "emmett42@welch.com",
"api_token":"543bjk6h3uh34n5j45nlk34j5k43n53j4b5jk34b5jk34",
"created_at": "2015-04-14 18:09:48",
"updated_at": "2015-04-14 18:09:48",
"courses": [
{
"id": 3,
"name": "Forro",
"pivot": {
"user_id": 3,
"course_id": 3
}
},
{
"id": 4,
"name": "Jiu Jitsu",
"pivot": {
"user_id": 3,
"course_id": 4
}
}
]
},
"message": "User with the id of 3"
}
app/Http/Controllers/ExamplesController.php
Data Transformers
You need them
<?php
namespace AppDataTransformers;
abstract class DataTransformer {
public function transformCollection($items, $method = 'transform')
{
return array_map([$this, $method], $items);
}
public abstract function transform($item);
}
app/DataTransformers/DataTransformer.php
<?php
namespace AppDataTransformers;
class UserTransformer extends DataTransformer{
public function transform($user)
{
return [
'id' => $user['id'],
'name' => $user['name'],
'email' => $user['email'],
];
}
}
app/DataTransformers/UserTransformer.php
{
"status": true,
"data": [
{
"id": 20,
"name": "Vance Jacobs",
"email": "callie.zieme@hotmail.com"
},
{
"id": 19,
"name": "Chesley Swift",
"email": "giovani72@schumm.com"
},
{
"id": 18,
"name": "Frederick Hilpert",
"email": "dameon.macejkovic@gmail.com"
}
],
"message": "Latest 3 users"
}
<?php
namespace AppDataTransformers;
class UserTransformer extends DataTransformer{
public function transform($user)
{
return [
'id' => $user['id'],
'name' => $user['name'],
'email' => $user['email'],
'courses' => (isset($user['courses']) && count($user['courses']))
? array_map([$this,'transformCourses'], $user['courses'])
: null,
];
}
public function transformCourses($course){
return [
'id' => $course['id'],
'name' => $course['name']
];
}
}
What about nested resources?
{
"status": true,
"data": [
{
"id": 20,
"name": "Vance Jacobs",
"email": "callie.zieme@hotmail.com",
"courses": null
},
{
"id": 19,
"name": "Chesley Swift",
"email": "giovani72@schumm.com",
"courses": [
{
"id": 2,
"name": "Samba"
},
{
"id": 3,
"name": "Forro"
}
]
},
{
"id": 18,
"name": "Frederick Hilpert",
"email": "dameon.macejkovic@gmail.com",
"courses": [
{
"id": 4,
"name": "Jiu Jitsu"
}
]
}
],
"message": "Latest 3 users"
}
Pretty error messages
public function render($request, Exception $e)
{
if ($e instanceof IlluminateDatabaseEloquentModelNotFoundException){
$message = [
'status' => false,
'error_code' => 2234,
'errors' => ["That resource doesn't exist"]
];
return response($message, 404);
}
if ($e instanceof SymfonyComponentHttpKernelExceptionNotFoundHttpException){
$message = [
'status' => false,
'error_code' => 1235,
'errors' => ["We don't have that kind of resources"]
];
return response($message, 404);
}
if ($e instanceof Exception){
$message = [
'status' => false,
'message' => $e->getMessage()
];
return response($message, $e->getCode());
}
return parent::render($request, $e);
}
}
app/Exceptions/Handler.php
STATUS 404 Not Found
{
"status": false,
"error_code": 1235,
"errors": [
"We don't have that kind of resources"
]
}
STATUS 404 Not Found
{
"status": false,
"error_code": 2234,
"errors": [
"That resource doesn't exist"
]
}
STATUS 418 I'm a teapot
{
"status": false,
"message": "I'm a teapot"
}
STATUS 500 Internal Server Error
{
"status": false,
"message": "Class 'User' not found"
}
Internal dispatcher
For your (probably) most important consumer
<?php
namespace AppHttp;
class InternalDispatcher {
public function release( $url, $method = 'GET', $input, $no_json) {
// Store the original input of the request
$originalInput = Request::input();
// Create request to the API, adding the no-json parameter, since it's an internal request
$request = Request::create($url, $method);
// Replace the input with the request instance input
Request::replace($input);
// Fetch the response
if ($no_json){
$content = Route::dispatch($request)->getContent();
$result = json_decode($content, 1);
}else{
$result = Route::dispatch($request)->getContent();
}
// Replace the input again with the original request input.
Request::replace($originalInput);
return $result;
}
public function withNoInput($url, $method = 'GET', $no_json = true){
$input = ['no-json'=>$no_json];
return $this->release($url, $method = 'GET', $input, $no_json);
}
}
app/Http/InternalDispatcher.php
STATUS 200 OK
{
"status": true,
"data": {
"latest_users": [
{
"id": 20,
"name": "Vance Jacobs",
"email": "callie.zieme@hotmail.com",
"courses": []
},
{
"id": 18,
"name": "Frederick Hilpert",
"email": "dameon.macejkovic@gmail.com",
"courses": []
}
],
"youngest_user": {
"id": 3,
"name": "Asia Towne DVM",
"email": "emmett42@welch.com",
"courses": [
{
"id": 3,
"name": "Forro"
},
{
"id": 4,
"name": "Jiu Jitsu"
}
]
}
},
"message": "Good data"
}
Thank you for listening!
Let the discussion begin :)

Contenu connexe

Tendances

Web service with Laravel
Web service with LaravelWeb service with Laravel
Web service with LaravelAbuzer Firdousi
 
Laravel Restful API and AngularJS
Laravel Restful API and AngularJSLaravel Restful API and AngularJS
Laravel Restful API and AngularJSBlake Newman
 
Getting to know Laravel 5
Getting to know Laravel 5Getting to know Laravel 5
Getting to know Laravel 5Bukhori Aqid
 
Laravel Beginners Tutorial 2
Laravel Beginners Tutorial 2Laravel Beginners Tutorial 2
Laravel Beginners Tutorial 2Vikas Chauhan
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkVance Lucas
 
Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.SWAAM Tech
 
ACL in CodeIgniter
ACL in CodeIgniterACL in CodeIgniter
ACL in CodeIgnitermirahman
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with LaravelMichael Peacock
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.xRyan Szrama
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发shaokun
 
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
 Connecting Content Silos: One CMS, Many Sites With The WordPress REST API Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Connecting Content Silos: One CMS, Many Sites With The WordPress REST APICaldera Labs
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weiboshaokun
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkJeremy Kendall
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutVic Metcalfe
 
Web services with laravel
Web services with laravelWeb services with laravel
Web services with laravelConfiz
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST APICaldera Labs
 

Tendances (20)

Web service with Laravel
Web service with LaravelWeb service with Laravel
Web service with Laravel
 
Laravel Restful API and AngularJS
Laravel Restful API and AngularJSLaravel Restful API and AngularJS
Laravel Restful API and AngularJS
 
Getting to know Laravel 5
Getting to know Laravel 5Getting to know Laravel 5
Getting to know Laravel 5
 
Laravel Beginners Tutorial 2
Laravel Beginners Tutorial 2Laravel Beginners Tutorial 2
Laravel Beginners Tutorial 2
 
Laravel 101
Laravel 101Laravel 101
Laravel 101
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 
Bullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-FrameworkBullet: The Functional PHP Micro-Framework
Bullet: The Functional PHP Micro-Framework
 
Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.
 
ACL in CodeIgniter
ACL in CodeIgniterACL in CodeIgniter
ACL in CodeIgniter
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with Laravel
 
Hello World on Slim Framework 3.x
Hello World on Slim Framework 3.xHello World on Slim Framework 3.x
Hello World on Slim Framework 3.x
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
Workshop Laravel 5.2
Workshop Laravel 5.2Workshop Laravel 5.2
Workshop Laravel 5.2
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
 Connecting Content Silos: One CMS, Many Sites With The WordPress REST API Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
Connecting Content Silos: One CMS, Many Sites With The WordPress REST API
 
More to RoC weibo
More to RoC weiboMore to RoC weibo
More to RoC weibo
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
Slim RedBeanPHP and Knockout
Slim RedBeanPHP and KnockoutSlim RedBeanPHP and Knockout
Slim RedBeanPHP and Knockout
 
Web services with laravel
Web services with laravelWeb services with laravel
Web services with laravel
 
Using the new WordPress REST API
Using the new WordPress REST APIUsing the new WordPress REST API
Using the new WordPress REST API
 

En vedette

jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010jeresig
 
How to restart windows 8
How to restart windows 8How to restart windows 8
How to restart windows 8mmeas
 
Nanoparticles drug delivery in cancer therapy
Nanoparticles drug delivery in cancer therapyNanoparticles drug delivery in cancer therapy
Nanoparticles drug delivery in cancer therapyroydebolina278
 
0046352b60861f1df3000000.pdf
0046352b60861f1df3000000.pdf0046352b60861f1df3000000.pdf
0046352b60861f1df3000000.pdfstoneshedadvisory
 
Brian Barrera Resume 5
Brian Barrera Resume 5Brian Barrera Resume 5
Brian Barrera Resume 5Brian Barrera
 
Android operating system
Android operating systemAndroid operating system
Android operating systemShahid Sayed
 
Unit 3 standards presentation
Unit 3 standards presentationUnit 3 standards presentation
Unit 3 standards presentationrebeccaneely
 
Каталог faberlic №6/2015
Каталог faberlic №6/2015Каталог faberlic №6/2015
Каталог faberlic №6/2015Larisa Batutina
 
Universal design - Towards a More Thorough Ethical and Theoretical Understan...
Universal design - Towards a More Thorough  Ethical and Theoretical Understan...Universal design - Towards a More Thorough  Ethical and Theoretical Understan...
Universal design - Towards a More Thorough Ethical and Theoretical Understan...Ilse Oosterlaken
 
Welzijn, diversiteit & actorschap; Een introductie op de 'capability' benadering
Welzijn, diversiteit & actorschap; Een introductie op de 'capability' benaderingWelzijn, diversiteit & actorschap; Een introductie op de 'capability' benadering
Welzijn, diversiteit & actorschap; Een introductie op de 'capability' benaderingIlse Oosterlaken
 
Pests infesting Fam. Solanaceae
Pests infesting Fam. SolanaceaePests infesting Fam. Solanaceae
Pests infesting Fam. SolanaceaeAsmaa Bedawy
 

En vedette (20)

jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010jQuery Keynote - Fall 2010
jQuery Keynote - Fall 2010
 
How to restart windows 8
How to restart windows 8How to restart windows 8
How to restart windows 8
 
Nanoparticles drug delivery in cancer therapy
Nanoparticles drug delivery in cancer therapyNanoparticles drug delivery in cancer therapy
Nanoparticles drug delivery in cancer therapy
 
0046352b60861f1df3000000.pdf
0046352b60861f1df3000000.pdf0046352b60861f1df3000000.pdf
0046352b60861f1df3000000.pdf
 
Evaluation question 2
Evaluation question 2Evaluation question 2
Evaluation question 2
 
Presentación1
Presentación1Presentación1
Presentación1
 
Brian Barrera Resume 5
Brian Barrera Resume 5Brian Barrera Resume 5
Brian Barrera Resume 5
 
NAV CV,,,,,,,
NAV CV,,,,,,,NAV CV,,,,,,,
NAV CV,,,,,,,
 
Android operating system
Android operating systemAndroid operating system
Android operating system
 
Unit 3 standards presentation
Unit 3 standards presentationUnit 3 standards presentation
Unit 3 standards presentation
 
Digital Etiquette
Digital EtiquetteDigital Etiquette
Digital Etiquette
 
Каталог faberlic №6/2015
Каталог faberlic №6/2015Каталог faberlic №6/2015
Каталог faberlic №6/2015
 
2016 13 cat_ru
2016 13 cat_ru2016 13 cat_ru
2016 13 cat_ru
 
2016 14 cat_ru
2016 14 cat_ru2016 14 cat_ru
2016 14 cat_ru
 
Universal design - Towards a More Thorough Ethical and Theoretical Understan...
Universal design - Towards a More Thorough  Ethical and Theoretical Understan...Universal design - Towards a More Thorough  Ethical and Theoretical Understan...
Universal design - Towards a More Thorough Ethical and Theoretical Understan...
 
Cat 16-2016-01
Cat 16-2016-01Cat 16-2016-01
Cat 16-2016-01
 
Digital literacy
Digital literacyDigital literacy
Digital literacy
 
Avalon_Case_Study
Avalon_Case_StudyAvalon_Case_Study
Avalon_Case_Study
 
Welzijn, diversiteit & actorschap; Een introductie op de 'capability' benadering
Welzijn, diversiteit & actorschap; Een introductie op de 'capability' benaderingWelzijn, diversiteit & actorschap; Een introductie op de 'capability' benadering
Welzijn, diversiteit & actorschap; Een introductie op de 'capability' benadering
 
Pests infesting Fam. Solanaceae
Pests infesting Fam. SolanaceaePests infesting Fam. Solanaceae
Pests infesting Fam. Solanaceae
 

Similaire à Bootstrat REST APIs with Laravel 5

Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPressMarko Heijnen
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hackingJeroen van Dijk
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn Wilker
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Designunodelostrece
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applicationselliando dias
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosDivante
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2markstory
 

Similaire à Bootstrat REST APIs with Laravel 5 (20)

Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Creating native apps with WordPress
Creating native apps with WordPressCreating native apps with WordPress
Creating native apps with WordPress
 
WordPress REST API hacking
WordPress REST API hackingWordPress REST API hacking
WordPress REST API hacking
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Fatc
FatcFatc
Fatc
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Zendcon 2007 Api Design
Zendcon 2007 Api DesignZendcon 2007 Api Design
Zendcon 2007 Api Design
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
Why is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenariosWhy is crud a bad idea - focus on real scenarios
Why is crud a bad idea - focus on real scenarios
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2
 

Dernier

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 

Dernier (20)

Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 

Bootstrat REST APIs with Laravel 5

  • 1. Bootstrap REST APIs with Laravel 5 Elena Kolevska
  • 2. www.speedtocontact.com Automated lead response system / call center in a browser
  • 4. SOAP! POST http://www.stgregorioschurchdc.org/cgi/websvccal.cgi HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: text/xml;charset=UTF-8 SOAPAction: "http://www.stgregorioschurchdc.org/Calendar#easter_date" Content-Length: 479 Host: www.stgregorioschurchdc.org Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5) <?xml version="1.0"?> <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cal="http://www.stgregorioschurchdc.org/Calendar"> <soapenv:Header/> <soapenv:Body> <cal:easter_date soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/ encoding/"> <year xsi:type="xsd:short">2014</year> </cal:easter_date> </soapenv:Body> </soapenv:Envelope>
  • 6. $header = 'Authorization: Basic' . base64_encode($username . ':' . $password);
  • 7.
  • 8. Authentication Middleware <?php namespace AppHttpMiddleware; use AppUser; use Closure; use IlluminateContractsAuthGuard; use IlluminateSupportFacadesHash; class AuthenticateOnce { public function handle($request, Closure $next) { if ($this->auth->onceBasic()) return response(['status'=>false, 'message'=>'Unauthorized'], 401, ['WWW-Authenticate' =>'Basic']); return $next($request); } protected $routeMiddleware = [ 'auth' => 'AppHttpMiddlewareAuthenticate', 'auth.basic' => 'IlluminateAuthMiddlewareAuthenticateWithBasicAuth', 'auth.basic.once' => 'AppHttpMiddlewareAuthenticateOnce', 'guest' => 'AppHttpMiddlewareRedirectIfAuthenticated', ];
  • 9. <?php Route::group(array('prefix' => 'api/v1/examples','middleware' => 'auth.basic.once'), function () { Route::get('1', 'ExamplesController@example1'); Route::get('2', 'ExamplesController@example2'); Route::get('3', 'ExamplesController@example3'); Route::get('4', 'ExamplesController@example4'); Route::get('5', 'ExamplesController@example5'); Route::get('6', 'ExamplesController@example6'); Route::get('7', 'ExamplesController@example7'); Route::get('8', 'ExamplesController@example8'); }); app/Http/routes.php
  • 10. Response format HTTP/1.1 200 OK Content-Type: application/json Connection: close X-Powered-By: PHP/5.6.3 Cache-Control: no-cache Date: Fri, 13 Apr 2015 16:37:57 GMT Transfer-Encoding: Identity {"status":true,"data":{"k1":"value1","k2":"value2"},"message":"Zero imagination for funny messages"}
  • 11. Most common HTTP status codes • 200 OK • 201 Created • 204 No Content • 400 Bad Request • 401 Unauthorized • 403 Forbidden • 404 Not Found • 409 Conflict • 500 Internal Server Error
  • 12. Response message format { "status": true, "data": { "k1": "value1", "k2": "value2" }, "message": "Zero imagination for funny messages" } { "status": false, "errors": { "e1": "Nope, it can't be done", "e2": "That can't be done either" }, "error_code": 12345, "message": "Zero imagination for funny messages" }
  • 14. app/Http/Controllers/ApiController.php <?php namespace AppHttpControllers; use IlluminateHttpRequest; use IlluminateRoutingResponseFactory; use IlluminateAuthGuard; use AppUser; class ApiController extends Controller{ public $response; public $request; public $auth; public function __construct(ResponseFactory $response, Request $request, Guard $auth) { $this->response = $response; $this->request = $request; $this->auth = $auth; $this->currentUser = $this->auth->user(); } }
  • 15. app/Http/Controllers/ApiController.php public function respond($data, $response_message, $status_code = 200) { //If this is an internal request we only return the data if ($this->request->input('no-json')) return $data; $message['status'] = true; if (isset($data)) $message['data'] = $data; if (isset($message)) $message['message'] = $response_message; if (isset($error_code)) $message['error_code'] = $error_code; return $this->response->json($message, $status_code); }
  • 16. app/Http/Controllers/ExamplesController.php <?php namespace AppHttpControllers; class ExamplesController extends ApiController { /** * Send back response with data * * @return Response */ public function example1() { $sample_data_array = ['k1'=>'value1', 'k2'=>'value2']; return $this->respond($sample_data_array, 'Message'); } }
  • 17.
  • 18. app/Http/Controllers/ApiController.php public function respondWithError($errors, $error_code, $status_code = 400) { if (is_string($errors)) $errors = [$errors]; $message = [ 'status' => false, 'errors' => $errors, 'error_code' => $error_code ]; return $this->response->json($message, $status_code); }} public function example3() { $error = "Can't be done"; return $this->respondWithError($error, 123, 500); } app/Http/Controllers/ExamplesController.php
  • 19.
  • 20. app/Http/Controllers/ApiController.php } /** * @param array $errors * @param int $status_code * @return Response */ public function respondWithValidationErrors($errors, $status_code = 400) { $message = [ 'status' => false, 'message' => "Please double check your form", 'validation_errors' => [$errors] ]; return $this->response->json($message, $status_code); } }
  • 21. app/Http/Controllers/ApiController.php public function respondCreated( $message = 'Resource created') { return $this->respond($message, 201); } public function respondUnauthorized( $error_code, $message = 'You are not authorized for this') { return $this->respondWithError($message, $error_code, 401); } public function respondNotFound( $error_code, $message = 'Resource not found') { return $this->respondWithError($message, $error_code, 404); } public function respondInternalError( $error_code, $message = 'Internal error') { return $this->respondWithError($message, $error_code, 500); } public function respondOk( $message = 'Done') { return $this->respond(null, $message, 200); }
  • 22. Always use fake data for testing https://github.com/fzaninotto/Faker
  • 23. <?php use IlluminateDatabaseSeeder; class UsersTableSeeder extends Seeder { public function run() { Eloquent::unguard(); $faker = FakerFactory::create(); for($i=1; $i < 20; $i++ ){ $data = [ 'name' => $faker->name, 'email' => $faker->email, 'password' => bcrypt('demodemo') ]; AppUser::create($data); } } } database/seeds/UsersTableSeeder.php
  • 24. Setting up the repositories
  • 25. app/Providers/RepoBindingServiceProvider.php <?php namespace AppProviders; use IlluminateSupportServiceProvider; class RepoBindingServiceProvider extends ServiceProvider { public function register() { $app = $this->app; $app->bind('AppRepositoriesContractsUsersInterface', function() { $repository = new AppRepositoriesUsersRepository(new AppUser); return $repository; }); } } * Register the service provider in the list of autoloaded service providers in config/app.php
  • 26. app/Repositories/BaseRepository.php <?php namespace AppRepositories; use IlluminateDatabaseEloquentModel; class BaseRepository { public function __construct(Model $model) { $this->model = $model; } public function create($data) { return $this->model->create($data); } public function find($id) { return $this->model->find($id); } public function delete($id) { return $this->model->destroy($id); } public function all() { return $this->model->all(); }
  • 27. app/Repositories/BaseRepository.php public function update($record, $data) { if (is_int($record)){ $this->model->find($record); $id = $record; } else { $this->model = $record; $id = $record->id; } return $this->model->where('id',$id)->update($data); } public function getById($id, $user_id = null, $with = null) { if (is_array($id)){ $result = $this->model->whereIn('id', $id); }else{ $result = $this->model->where('id', $id); } if ($user_id) $result->where('user_id', $user_id); if ($with) $result->with($with); if (is_array($id)){ return $result->get(); return $result->first(); }
  • 28. public function example5() { $data = App::make('AppRepositoriesContractsUsersInterface')->getById(3,null,['courses']); return $this->respond($data,"All users"); } { "status": true, "data": { "id": 3, "name": "Asia Towne DVM", "email": "emmett42@welch.com", "api_token":"543bjk6h3uh34n5j45nlk34j5k43n53j4b5jk34b5jk34", "created_at": "2015-04-14 18:09:48", "updated_at": "2015-04-14 18:09:48", "courses": [ { "id": 3, "name": "Forro", "pivot": { "user_id": 3, "course_id": 3 } }, { "id": 4, "name": "Jiu Jitsu", "pivot": { "user_id": 3, "course_id": 4 } } ] }, "message": "User with the id of 3" } app/Http/Controllers/ExamplesController.php
  • 30. <?php namespace AppDataTransformers; abstract class DataTransformer { public function transformCollection($items, $method = 'transform') { return array_map([$this, $method], $items); } public abstract function transform($item); } app/DataTransformers/DataTransformer.php <?php namespace AppDataTransformers; class UserTransformer extends DataTransformer{ public function transform($user) { return [ 'id' => $user['id'], 'name' => $user['name'], 'email' => $user['email'], ]; } } app/DataTransformers/UserTransformer.php
  • 31. { "status": true, "data": [ { "id": 20, "name": "Vance Jacobs", "email": "callie.zieme@hotmail.com" }, { "id": 19, "name": "Chesley Swift", "email": "giovani72@schumm.com" }, { "id": 18, "name": "Frederick Hilpert", "email": "dameon.macejkovic@gmail.com" } ], "message": "Latest 3 users" }
  • 32. <?php namespace AppDataTransformers; class UserTransformer extends DataTransformer{ public function transform($user) { return [ 'id' => $user['id'], 'name' => $user['name'], 'email' => $user['email'], 'courses' => (isset($user['courses']) && count($user['courses'])) ? array_map([$this,'transformCourses'], $user['courses']) : null, ]; } public function transformCourses($course){ return [ 'id' => $course['id'], 'name' => $course['name'] ]; } } What about nested resources?
  • 33. { "status": true, "data": [ { "id": 20, "name": "Vance Jacobs", "email": "callie.zieme@hotmail.com", "courses": null }, { "id": 19, "name": "Chesley Swift", "email": "giovani72@schumm.com", "courses": [ { "id": 2, "name": "Samba" }, { "id": 3, "name": "Forro" } ] }, { "id": 18, "name": "Frederick Hilpert", "email": "dameon.macejkovic@gmail.com", "courses": [ { "id": 4, "name": "Jiu Jitsu" } ] } ], "message": "Latest 3 users" }
  • 35. public function render($request, Exception $e) { if ($e instanceof IlluminateDatabaseEloquentModelNotFoundException){ $message = [ 'status' => false, 'error_code' => 2234, 'errors' => ["That resource doesn't exist"] ]; return response($message, 404); } if ($e instanceof SymfonyComponentHttpKernelExceptionNotFoundHttpException){ $message = [ 'status' => false, 'error_code' => 1235, 'errors' => ["We don't have that kind of resources"] ]; return response($message, 404); } if ($e instanceof Exception){ $message = [ 'status' => false, 'message' => $e->getMessage() ]; return response($message, $e->getCode()); } return parent::render($request, $e); } } app/Exceptions/Handler.php
  • 36. STATUS 404 Not Found { "status": false, "error_code": 1235, "errors": [ "We don't have that kind of resources" ] } STATUS 404 Not Found { "status": false, "error_code": 2234, "errors": [ "That resource doesn't exist" ] } STATUS 418 I'm a teapot { "status": false, "message": "I'm a teapot" } STATUS 500 Internal Server Error { "status": false, "message": "Class 'User' not found" }
  • 37. Internal dispatcher For your (probably) most important consumer
  • 38. <?php namespace AppHttp; class InternalDispatcher { public function release( $url, $method = 'GET', $input, $no_json) { // Store the original input of the request $originalInput = Request::input(); // Create request to the API, adding the no-json parameter, since it's an internal request $request = Request::create($url, $method); // Replace the input with the request instance input Request::replace($input); // Fetch the response if ($no_json){ $content = Route::dispatch($request)->getContent(); $result = json_decode($content, 1); }else{ $result = Route::dispatch($request)->getContent(); } // Replace the input again with the original request input. Request::replace($originalInput); return $result; } public function withNoInput($url, $method = 'GET', $no_json = true){ $input = ['no-json'=>$no_json]; return $this->release($url, $method = 'GET', $input, $no_json); } } app/Http/InternalDispatcher.php
  • 39. STATUS 200 OK { "status": true, "data": { "latest_users": [ { "id": 20, "name": "Vance Jacobs", "email": "callie.zieme@hotmail.com", "courses": [] }, { "id": 18, "name": "Frederick Hilpert", "email": "dameon.macejkovic@gmail.com", "courses": [] } ], "youngest_user": { "id": 3, "name": "Asia Towne DVM", "email": "emmett42@welch.com", "courses": [ { "id": 3, "name": "Forro" }, { "id": 4, "name": "Jiu Jitsu" } ] } }, "message": "Good data" }
  • 40. Thank you for listening! Let the discussion begin :)