Building Scalable
applications with Laravel
Laravel - PHP Framework For Web Artisans
Lumen
The stunningly fast micro-framework by Laravel.
Lumen is the perfect solution for
building Laravel based
micro-services and blazing fast APIs
Laravel ● Middleware
● Dependency Injection
● Filesystem / Cloud Storage
● Queues
● Task Scheduling
● Database
○ Query Builder
○ Migrations
○ Seeding
● LUCID Architecture
Middleware
HTTP middleware provide a convenient mechanism for filtering
HTTP requests entering your application.
● Maintenance
● Authentication
● CSRF protection
MeetingMogul
Validate twilio requests (Header Signature)
<?php
namespace AppHttpMiddleware;
use Log;
use Closure;
use AppRepositoriesTwilioAccountTwilioAccountRepositoryInterface;
class ValidateTwilioRequestMiddleware
{
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (!$this->validateRequest($request)) {
throw new SymfonyComponentHttpKernelExceptionUnauthorizedHttpException('Twilio', 'You are not authorized to access this
resource.');
}
return $next($request);
}
}
Dependency Injection
Laravel provides a convenient way to inject dependencies
seemlessly.
<?php
namespace Database;
class Database
{
protected $adapter;
public function __construct(AdapterInterface $adapter)
{
$this->adapter = $adapter;
}
}
<?php
namespace AppApiv1Controllers;
use AppApiTransformersMessageStatusTransformer;
use AppRepositoriesUserUserRepositoryInterface;
/**
* Message Resource
*
* @Resource("Message", uri="/messages")
*/
class MessageController extends BaseController
{
protected $userRepo;
public function __construct(Request $request, UserRepositoryInterface $userRepo)
{
parent::__construct($request);
$this->userRepo = $userRepo;
}
protected function setMessagingStatus(Request $request)
{
$this->userRepo->createOrUpdateProfile($this->auth->user(), $request->all());
return (['message' => 'Message Status updated successfully.']);
}
}
<?php
namespace AppRepositories;
use IlluminateSupportServiceProvider;
class RepositoryServiceProvider extends ServiceProvider
{
/**
* @var array
*/
protected $bindings = [
UserUserRepositoryInterface::class => UserUserRepository::class,
BuddyBuddyRepositoryInterface::class => BuddyBuddyRepository::class,
ProfileProfileRepositoryInterface::class => ProfileProfileRepository::class,
ContentContentRepositoryInterface::class => ContentContentRepository::class,
];
/**
* @return void
*/
public function register()
{
foreach ($this->bindings as $interface => $implementation) {
$this->app->bind($interface, $implementation);
}
}
}
Cloud Storage
Laravel provides a powerful filesystem abstraction. It
provides simple to use drivers for working with Local
filesystems, Amazon S3 and Rackspace Cloud Storage. Even
better, it's amazingly simple to switch between these
storage options as the API remains the same for each system.
Cloud Storage
public function updateAvatar(Request $request, $id)
{
$user = User::findOrFail($id);
Storage::put(
'avatars/'.$user->id,
file_get_contents($request->file('avatar')->getRealPath())
);
}
Queues
The Laravel queue service provides a unified API across a
variety of different queue back-ends.
$job = (new SendReminderEmail($user))->onQueue('emails');
$this->dispatch($job);
Available Queue Drivers:
Database, Beanstalkd, Amazon SQS, Redis, and synchronous
(for local use) driver
Task Scheduling
The Laravel command scheduler allows you to fluently and
expressively define your command schedule within Laravel
itself, and only a single Cron entry is needed on your
server.
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
$schedule->command('emails:send')->weekly()->mondays()->at('13:00');
$schedule->command('emails:send')->withoutOverlapping();
}
Database
Query Builder
Migrations
Seeding
Elequent ORM
Query Builder
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
Migrations
Migrations are like version control for your database.
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
});
Seeding
Laravel includes a simple method of seeding your database
with test data using seed classes.
<?php
use IlluminateDatabaseSeeder;
use IlluminateDatabaseEloquentModel;
class DatabaseSeeder extends Seeder
{
public function run()
{
DB::table('users')->insert([
'name' => str_random(10),
'email' => str_random(10).'@gmail.com',
'password' => bcrypt('secret'),
]);
}
}
Eloquent ORM
● Convention over configuration
● Timestamps automatically managed (Carbon)
● Soft Deleting
● Query Scopes
Eloquent ORM - Soft Delete
● Active Record implementation
php artisan make:model User --migration
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentSoftDeletes;
class Flight extends Model
{
use SoftDeletes;
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
}
LUCID
Architecture
An Architecture is a pattern of
connected Structures.
LUCID architecture Designed at vinelab
to get rid of rotting/legacy code.
Architecture
Controller View
Model
Service/
Domain
Communicate Structures
● No more legacy code
● Defines Terminology
● Comprehensive, No limitations
● Complements Laravel’s Design
● Balance performance and design
Lucid Components
Feature
Job
Service
Lucid * Feature
● As described in business, as a class name
● Runs Jobs - Steps in the process of accomplishment
CreateArticleFeature
LoginUserFeature
Controller Feature
Serves
Controller serves Feature
Lucid * Job
A class that does one thing; responsible for the business logic
● Validate Article Input
● Generate Slug
● Upload Files To CDN
● Save Article
● Respond With Json
CreateArticleFeature
Lucid * Job
A class that does one thing; responsible for the business logic
● ValidateArticleInputJob
● GenerateSlugJob
● UploadFilesToCDNJob
● SaveArticleJob
● RespondWithJsonJob
CreateArticleFeature
Lucid * Job
A class that does one thing; responsible for the business logic
Lucid * Service
Implements Features and serves them through controllers
● Website
● Api
● Backend
Lucid * Domains
Responsible for the entities; exposing their
functionalities through Jobs
Lucid * Domains
● Article
○ GetPublishedArticlesJob
○ SaveArticleJob
○ ValidateArticleInputJob
● CDN
○ UploadFilesToCdnJob
● HTTP
○ RespondWithJsonJob
Lucid * Principles
● Controllers serve Features
● Avoid Cross-Domain Communication
● Avoid Cross-Job Communication
Best Practices
● Standards (PHP-FIG)
○ Autoloading
○ Code Style
● Interfaces
● Components
○ Carbon
○ Intervention
● Pull Requests &
● Code Reviews on GitHub
Question & Answer

Building Scalable Applications with Laravel

  • 1.
    Building Scalable applications withLaravel Laravel - PHP Framework For Web Artisans
  • 2.
    Lumen The stunningly fastmicro-framework by Laravel. Lumen is the perfect solution for building Laravel based micro-services and blazing fast APIs
  • 3.
    Laravel ● Middleware ●Dependency Injection ● Filesystem / Cloud Storage ● Queues ● Task Scheduling ● Database ○ Query Builder ○ Migrations ○ Seeding ● LUCID Architecture
  • 4.
    Middleware HTTP middleware providea convenient mechanism for filtering HTTP requests entering your application. ● Maintenance ● Authentication ● CSRF protection MeetingMogul Validate twilio requests (Header Signature)
  • 5.
    <?php namespace AppHttpMiddleware; use Log; useClosure; use AppRepositoriesTwilioAccountTwilioAccountRepositoryInterface; class ValidateTwilioRequestMiddleware { /** * Handle an incoming request. * * @param IlluminateHttpRequest $request * @param Closure $next * @return mixed */ public function handle($request, Closure $next) { if (!$this->validateRequest($request)) { throw new SymfonyComponentHttpKernelExceptionUnauthorizedHttpException('Twilio', 'You are not authorized to access this resource.'); } return $next($request); } }
  • 6.
    Dependency Injection Laravel providesa convenient way to inject dependencies seemlessly. <?php namespace Database; class Database { protected $adapter; public function __construct(AdapterInterface $adapter) { $this->adapter = $adapter; } }
  • 7.
    <?php namespace AppApiv1Controllers; use AppApiTransformersMessageStatusTransformer; useAppRepositoriesUserUserRepositoryInterface; /** * Message Resource * * @Resource("Message", uri="/messages") */ class MessageController extends BaseController { protected $userRepo; public function __construct(Request $request, UserRepositoryInterface $userRepo) { parent::__construct($request); $this->userRepo = $userRepo; } protected function setMessagingStatus(Request $request) { $this->userRepo->createOrUpdateProfile($this->auth->user(), $request->all()); return (['message' => 'Message Status updated successfully.']); } }
  • 8.
    <?php namespace AppRepositories; use IlluminateSupportServiceProvider; classRepositoryServiceProvider extends ServiceProvider { /** * @var array */ protected $bindings = [ UserUserRepositoryInterface::class => UserUserRepository::class, BuddyBuddyRepositoryInterface::class => BuddyBuddyRepository::class, ProfileProfileRepositoryInterface::class => ProfileProfileRepository::class, ContentContentRepositoryInterface::class => ContentContentRepository::class, ]; /** * @return void */ public function register() { foreach ($this->bindings as $interface => $implementation) { $this->app->bind($interface, $implementation); } } }
  • 9.
    Cloud Storage Laravel providesa powerful filesystem abstraction. It provides simple to use drivers for working with Local filesystems, Amazon S3 and Rackspace Cloud Storage. Even better, it's amazingly simple to switch between these storage options as the API remains the same for each system.
  • 10.
    Cloud Storage public functionupdateAvatar(Request $request, $id) { $user = User::findOrFail($id); Storage::put( 'avatars/'.$user->id, file_get_contents($request->file('avatar')->getRealPath()) ); }
  • 11.
    Queues The Laravel queueservice provides a unified API across a variety of different queue back-ends. $job = (new SendReminderEmail($user))->onQueue('emails'); $this->dispatch($job); Available Queue Drivers: Database, Beanstalkd, Amazon SQS, Redis, and synchronous (for local use) driver
  • 12.
    Task Scheduling The Laravelcommand scheduler allows you to fluently and expressively define your command schedule within Laravel itself, and only a single Cron entry is needed on your server. protected function schedule(Schedule $schedule) { $schedule->call(function () { DB::table('recent_users')->delete(); })->daily(); $schedule->command('emails:send')->weekly()->mondays()->at('13:00'); $schedule->command('emails:send')->withoutOverlapping(); }
  • 13.
  • 14.
    Query Builder DB::transaction(function (){ DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); });
  • 15.
    Migrations Migrations are likeversion control for your database. Schema::create('users', function (Blueprint $table) { $table->increments('id'); });
  • 16.
    Seeding Laravel includes asimple method of seeding your database with test data using seed classes. <?php use IlluminateDatabaseSeeder; use IlluminateDatabaseEloquentModel; class DatabaseSeeder extends Seeder { public function run() { DB::table('users')->insert([ 'name' => str_random(10), 'email' => str_random(10).'@gmail.com', 'password' => bcrypt('secret'), ]); } }
  • 17.
    Eloquent ORM ● Conventionover configuration ● Timestamps automatically managed (Carbon) ● Soft Deleting ● Query Scopes
  • 18.
    Eloquent ORM -Soft Delete ● Active Record implementation php artisan make:model User --migration <?php namespace App; use IlluminateDatabaseEloquentModel; use IlluminateDatabaseEloquentSoftDeletes; class Flight extends Model { use SoftDeletes; /** * The attributes that should be mutated to dates. * * @var array */ protected $dates = ['deleted_at']; }
  • 19.
    LUCID Architecture An Architecture isa pattern of connected Structures. LUCID architecture Designed at vinelab to get rid of rotting/legacy code.
  • 20.
  • 21.
  • 22.
    ● No morelegacy code ● Defines Terminology ● Comprehensive, No limitations ● Complements Laravel’s Design ● Balance performance and design
  • 23.
  • 24.
    Lucid * Feature ●As described in business, as a class name ● Runs Jobs - Steps in the process of accomplishment CreateArticleFeature LoginUserFeature Controller Feature Serves
  • 25.
  • 30.
    Lucid * Job Aclass that does one thing; responsible for the business logic ● Validate Article Input ● Generate Slug ● Upload Files To CDN ● Save Article ● Respond With Json CreateArticleFeature
  • 31.
    Lucid * Job Aclass that does one thing; responsible for the business logic ● ValidateArticleInputJob ● GenerateSlugJob ● UploadFilesToCDNJob ● SaveArticleJob ● RespondWithJsonJob CreateArticleFeature
  • 32.
    Lucid * Job Aclass that does one thing; responsible for the business logic
  • 37.
    Lucid * Service ImplementsFeatures and serves them through controllers ● Website ● Api ● Backend
  • 40.
    Lucid * Domains Responsiblefor the entities; exposing their functionalities through Jobs
  • 41.
    Lucid * Domains ●Article ○ GetPublishedArticlesJob ○ SaveArticleJob ○ ValidateArticleInputJob ● CDN ○ UploadFilesToCdnJob ● HTTP ○ RespondWithJsonJob
  • 43.
    Lucid * Principles ●Controllers serve Features ● Avoid Cross-Domain Communication ● Avoid Cross-Job Communication
  • 44.
    Best Practices ● Standards(PHP-FIG) ○ Autoloading ○ Code Style ● Interfaces ● Components ○ Carbon ○ Intervention ● Pull Requests & ● Code Reviews on GitHub
  • 45.

Editor's Notes

  • #3 API architecture We need to use micro frameworks for APIs
  • #4 Laravel provides these features and it sets it apart from other PHP frameworks.
  • #5 Same as filters in Yii Can be defined Globally with route group
  • #6 Validate all requests coming from Twilio
  • #7 Problems DI solves are “Inversion of Control” and “Dependency Inversion Principle” Loosening dependencies by separate instantiation Depend on abstractions rather than concretions
  • #8 Dependency of UserRepository is injected automatically through Service Containers
  • #9 Service container bindings are registered in Service Providers We can replace these bindings with mock classes and testing can become simpler.
  • #10 Laravel uses flysystem library to provide filesystem abstraction.
  • #18 I guess Convention over Configuration is not specific to ORM In Laravel it has more use in ORM as compared to Ruby On Rails in which most of the framework features work on this principle
  • #20 Architecture: Outcome depends on how structures are connected. (DNA -> dinosaur) Old/legacy projects like Shredd/MTSobek New developer needs to understand where each piece of code resides
  • #21 How Structures (Classes) like any service connected to other part of our code High level or Top level view. An expression of a Viewpoint. Communicate Structures Large application code New developer MVC example
  • #22 Why use architecture Utility and Helper Classes Single Responsibility Principle
  • #26 Thin controller
  • #45 Autoloading (PSR-4) Code Style (PSR-2)