SlideShare une entreprise Scribd logo
1  sur  110
Télécharger pour lire hors ligne
COMPREHENSIVE 
VALIDATION WITH 
LARAVEL 4 
Kirk Bushell
INTRODUCTION 
● Developer - 15 years experience 
● Technical lead - Tectonic Digital 
● Software architect - Award Force - http://awardforce.com 
● Information Technologies Coordinator - Engineers without Borders 
● Technical writer - http://kirkbushell.me 
● Talk comments/feedback: https://joind.in/talk/view/11690 
● Github - https://github.com/kirkbushell
“ALWAYS PASS ON WHAT YOU LEARN”
“ALWAYS PASS ON WHAT YOU LEARN” 
- YODA
WHY CARE ABOUT VALIDATION?
WHY CARE ABOUT VALIDATION? 
● Validation can get messy - really quick
WHY CARE ABOUT VALIDATION? 
● Validation can get messy - really quick 
● We do it. All the time.
WHY CARE ABOUT VALIDATION? 
● Validation can get messy - really quick 
● We do it. All the time. 
● Lots of architectural discussion in the community
INSPIRATION 
● What started this thought process?
INSPIRATION 
● What started this thought process? 
● Jeffrey Way’s twitter post earlier this year about where people put their 
validation rules.
INSPIRATION 
● What started this thought process? 
● Jeffrey Way’s twitter post earlier this year about where people put their 
validation rules. 
● Jason Lewis’ article on advanced validation: http://jasonlewis. 
me/article/laravel-advanced-validation
INSPIRATION 
● What started this thought process? 
● Jeffrey Way’s twitter post earlier this year about where people put their 
validation rules. 
● Jason Lewis’ article on advanced validation: http://jasonlewis. 
me/article/laravel-advanced-validation 
● Lots of posts about validation on forums, twitter.etc.
BUT FIRST, A FEW POINTS
BUT FIRST, A FEW POINTS 
● This approach is best suited to medium-large applications
BUT FIRST, A FEW POINTS 
● This approach is best suited to medium-large applications 
● We’re going to use “users” as a set of use-cases to demonstrate this 
approach and style to the handling of validation
BUT FIRST, A FEW POINTS 
● This approach is best suited to medium-large applications 
● We’re going to use “users” as a set of use-cases to demonstrate this 
approach and style to the handling of validation 
● There will be a little code
BUT FIRST, A FEW POINTS 
● This approach is best suited to medium-large applications 
● We’re going to use “users” as a set of use-cases to demonstrate this 
approach and style to the handling of validation 
● There will be a little code (Sorry)
WHAT WILL WE COVER
WHAT WILL WE COVER 
● A brief history of MVC (to provide context)
WHAT WILL WE COVER 
● A brief history of MVC (to provide context) 
● Good validation practice (resource vs use-case)
WHAT WILL WE COVER 
● A brief history of MVC (to provide context) 
● Good validation practice (resource vs use-case) 
● How to architect your validation rules so that they can grow, adhering to 
SOLID design principles
WHAT WILL WE COVER 
● A brief history of MVC (to provide context) 
● Good validation practice (resource vs use-case) 
● How to architect your validation rules so that they can grow, adhering to 
SOLID design principles 
● Where validation should go (controllers, models, repositories - where?)
WHAT WILL WE COVER 
● A brief history of MVC (to provide context) 
● Good validation practice (resource vs use-case) 
● How to architect your validation rules so that they can grow, adhering to 
SOLID design principles 
● Where validation should go (controllers, models, repositories - where?) 
● Use exceptions to alter program flow and provide greater readability
ASSUMPTIONS 
● You know a thing or two about Laravel 4’s validation functionality
ASSUMPTIONS 
● You know a thing or two about Laravel 4’s validation functionality 
● You understand how to use Laravel’s IoC features
ASSUMPTIONS 
● You know a thing or two about Laravel 4’s validation functionality 
● You understand how to use Laravel’s IoC features 
● You understand the importance of a separation of concerns (if not, we’ll 
cover this a little)
ASSUMPTIONS 
● You know a thing or two about Laravel 4’s validation functionality 
● You understand how to use Laravel’s IoC features 
● You understand the importance of a separation of concerns (if not, we’ll 
cover this a little) 
● You’ve dealt with growing validation concerns before (or not)
A BRIEF HISTORY OF MVC
A BRIEF HISTORY OF MVC 
● No one knew
A BRIEF HISTORY OF MVC 
● No one knew 
● Fat controllers
A BRIEF HISTORY OF MVC 
● No one knew 
● Fat controllers 
● Skinny controllers, fat models
A BRIEF HISTORY OF MVC 
● No one knew 
● Fat controllers 
● Skinny controllers, fat models 
● Hexagonal architecture (service layers)
A BRIEF HISTORY OF MVC 
● No one knew 
● Fat controllers 
● Skinny controllers, fat models 
● Hexagonal architecture (service layers) 
● Repositories
A BRIEF HISTORY OF MVC 
● No one knew 
● Fat controllers 
● Skinny controllers, fat models 
● Hexagonal architecture (service layers) 
● Repositories 
● Validation?
THE REPOSITORY PATTERN 
● Why?
THE REPOSITORY PATTERN 
● Why? 
● Helped clean up models
THE REPOSITORY PATTERN 
● Why? 
● Helped clean up models 
● Ensured a common interface for establishing data storage access
THE REPOSITORY PATTERN 
● Why? 
● Helped clean up models 
● Ensured a common interface for establishing data storage access 
● Enabled us to easily swap out storage formats, caching mechanisms and 
more…
THE REPOSITORY PATTERN 
● Why? 
● Helped clean up models 
● Ensured a common interface for establishing data storage access 
● Enabled us to easily swap out storage formats, caching mechanisms and 
more… 
● What about validation?
WHY NOT ON THE MODEL? 
● Breaks the Single Responsibility Principle
WHY NOT ON THE MODEL? 
● Breaks the Single Responsibility Principle 
● Makes no sense if you’re using repositories
WHY NOT ON THE MODEL? 
● Breaks the Single Responsibility Principle 
● Makes no sense if you’re using repositories 
● Should be called as part of the service layer
WHY NOT ON THE MODEL? 
● Breaks the Single Responsibility Principle 
● Makes no sense if you’re using repositories 
● Should be called as part of the service layer 
● Validation is its own domain of logic
WHY NOT ON THE MODEL? 
● Breaks the Single Responsibility Principle 
● Makes no sense if you’re using repositories 
● Should be called as part of the service layer 
● Validation is its own domain of logic 
● I don’t like model-based validation… it smells.
WHY NOT ON THE MODEL? 
● Breaks the Single Responsibility Principle 
● Makes no sense if you’re using repositories 
● Should be called as part of the service layer 
● Validation is its own domain of logic 
● I don’t like model-based validation… it smells. 
● But kirk… why?
HOW I VIEW MODELS 
● Our models are already a mess of various responsibilities
HOW I VIEW MODELS 
● Our models are already a mess of various responsibilities 
● What table or collection to talk to
HOW I VIEW MODELS 
● Our models are already a mess of various responsibilities 
● What table or collection to talk to 
● Relationships
HOW I VIEW MODELS 
● Our models are already a mess of various responsibilities 
● What table or collection to talk to 
● Relationships 
● Querying
HOW I VIEW MODELS 
● Our models are already a mess of various responsibilities 
● What table or collection to talk to 
● Relationships 
● Querying 
● All part of active record. Validation isn’t.
HOW I VIEW MODELS 
● Our models are already a mess of various responsibilities 
● What table or collection to talk to 
● Relationships 
● Querying 
● All part of active record. Validation isn’t. 
● They can (and arguably - should) be used as schema descriptors for your 
application
class User extends Eloquent 
{ 
public $rules = [ 
‘name’ => [‘required’, ‘min:8’], 
‘address’ => ‘required’ 
]; 
public function save() { 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new Exception(‘Ugh, y u no provide good datums!?’); 
return parent::save(); 
} 
}
class User extends Eloquent 
{ 
public $rules = [ 
‘name’ => [‘required’, ‘min:8’], 
‘address’ => ‘required’ 
]; 
public function save() { 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new Exception(‘Ugh, y u no provide good datums!?’); 
return parent::save(); 
} 
}
class User extends Eloquent 
{ 
public $rules = [ 
‘name’ => [‘required’, ‘min:8’], 
‘address’ => ‘required’ 
]; 
public function save() { 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new Exception(‘Ugh, y u no provide good datums!?’); 
return parent::save(); 
} 
}
class User extends Eloquent 
{ 
public $rules = [ 
‘name’ => [‘required’, ‘min:8’], 
‘address’ => ‘required’ 
]; 
public function save() { 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if (!$validator->fails()) 
throw new Exception(‘Ugh, y u no provide good datums!?’); 
return parent::save(); 
} 
}
BUT… CAN WE DO BETTER?
OF COURSE WE CAN
OF COURSE WE CAN 
;)
A CUSTOM VALIDATOR 
● Defines an approach to handle validation use-cases
A CUSTOM VALIDATOR 
● Defines an approach to handle validation use-cases 
● Easier to use and read in our code
A CUSTOM VALIDATOR 
● Defines an approach to handle validation use-cases 
● Easier to use and read in our code 
● Provides the ability to automatically handle validation errors
A CUSTOM VALIDATOR 
● Defines an approach to handle validation use-cases 
● Easier to use and read in our code 
● Provides the ability to automatically handle validation errors 
● Wraps Laravel’s validator so we’re not reinventing the wheel
A CUSTOM VALIDATOR 
● Defines an approach to handle validation use-cases 
● Easier to use and read in our code 
● Provides the ability to automatically handle validation errors 
● Wraps Laravel’s validator so we’re not reinventing the wheel 
● Inspired by Jason Lewis’ validator (originally based on L3): 
http://jasonlewis.me/article/laravel-advanced-validation
abstract class Validation 
{ 
protected $rules = []; 
protected $messages = []; 
protected $input = []; 
public function __construct(array $input = []) { 
$this->input = $input; 
} 
public function validate() { 
$rules = $this->getRules(); 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new ValidationException($validator);
abstract class Validation 
{ 
protected $rules = []; 
protected $messages = []; 
protected $input = []; 
public function __construct(array $input = []) { 
$this->input = $input; 
} 
public function validate() { 
$rules = $this->getRules(); 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new ValidationException($validator);
abstract class Validation 
{ 
protected $rules = []; 
protected $messages = []; 
protected $input = []; 
public function __construct(array $input = []) { 
$this->input = $input; 
} 
public function validate() { 
$rules = $this->getRules(); 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new ValidationException($validator);
abstract class Validation 
{ 
protected $rules = []; 
protected $messages = []; 
protected $input = []; 
public function __construct(array $input = []) { 
$this->input = $input; 
} 
public function validate() { 
$rules = $this->getRules(); 
$validator = Validator::make($this->getInput(), $this->rules); 
if ($validator->fails()) 
throw new ValidationException($validator);
abstract class Validation 
{ 
public function validate() { 
$rules = $this->getRules(); 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new ValidationException($validator); 
} 
public function getRules() { 
return $this->rules; 
} 
}
abstract class Validation 
{ 
public function getRules() { 
return $this->rules; 
} 
public function getInput() { 
return $this->input; 
} 
}
abstract class Validation 
{ 
public function validate() { 
$rules = $this->getRules(); 
$validator = Validator::make($this->getAttributes(), $this->rules); 
if ($validator->fails()) 
throw new ValidationException($validator); 
} 
public function getRules() { 
return $this->rules; 
} 
}
class ValidationException extends Exception 
{ 
public function __construct(Validator $validator) 
{ 
$this->message = 'Validation has failed, or something.'; 
$this->validator = $validator; 
} 
public function getErrors() 
{ 
return $this->validator->messages(); 
}
class ValidationException extends Exception 
{ 
public function __construct(Validator $validator) 
{ 
$this->message = 'Validation has failed, or something.'; 
$this->validator = $validator; 
} 
public function getErrors() 
{ 
return $this->validator->messages(); 
}
class ValidationException extends Exception 
{ 
public function __construct(Validator $validator) 
{ 
$this->message = 'Validation has failed, or something.'; 
$this->validator = $validator; 
} 
public function getErrors() 
{ 
return $this->validator->messages(); 
}
A VALIDATION USE-CASE 
● User registration (everyone loves registration… right?)
A VALIDATION USE-CASE 
● User registration (everyone loves registration… right?) 
● We’ll need to define a validator specific to this requirement
A VALIDATION USE-CASE 
● User registration (everyone loves registration… right?) 
● We’ll need to define a validator specific to this requirement 
● Let’s go with the usual:
A VALIDATION USE-CASE 
● User registration (everyone loves registration… right?) 
● We’ll need to define a validator specific to this requirement 
● Let’s go with the usual: 
○ Username
A VALIDATION USE-CASE 
● User registration (everyone loves registration… right?) 
● We’ll need to define a validator specific to this requirement 
● Let’s go with the usual: 
○ Username 
○ Email address
A VALIDATION USE-CASE 
● User registration (everyone loves registration… right?) 
● We’ll need to define a validator specific to this requirement 
● Let’s go with the usual: 
○ Username 
○ Email address 
○ Password
class UserRegistrationValidation extends Validation 
{ 
protected $rules = [ 
‘username’ => [‘required’, ‘min:3’], 
‘email’ => [‘required’, ‘email’], 
‘password’ => [‘required’, ‘min:8’] 
]; 
}
class UserRegistrationValidation extends Validation 
{ 
public function getRules() 
{ 
$rules = [ 
‘username’ => [‘required’, ‘min:3’], 
‘email’ => [‘required’, ‘email’], 
‘password’ => [‘required’, ‘min:8’] 
]; 
return $rules; 
} 
}
SO… HOW DO WE USE THIS? 
● Utilise our validation for user registration
SO… HOW DO WE USE THIS? 
● Utilise our validation for user registration 
● Provide it with the required $input (in this case, probably Input::get())
SO… HOW DO WE USE THIS? 
● Utilise our validation for user registration 
● Provide it with the required $input (in this case, probably Input::get()) 
● Then call the validate function
SO… HOW DO WE USE THIS? 
● Utilise our validation for user registration 
● Provide it with the required $input (in this case, probably Input::get()) 
● Then call the validate function 
● Handle the onslaught of errors!
SO… HOW DO WE USE THIS? 
● Utilise our validation for user registration 
● Provide it with the required $input (in this case, probably Input::get()) 
● Then call the validate function 
● Handle the onslaught of errors! 
● Let’s see an example, shall we?
// UserController 
public function postRegister() 
{ 
$input = Input::get(); 
try { 
App::make(‘UserRegistrationValidation’, [$input])->validate(); 
} 
catch (ValidationException $e) { 
// Handle errors 
} 
// Create a response 
return User::create($input); 
}
BUT WAIT...
THAT’S UGLY.
AND LARAVEL CAN HELP :)
EXCEPTIONS FOR DAYS 
● We can use Laravel’s own error-handling to our advantage
EXCEPTIONS FOR DAYS 
● We can use Laravel’s own error-handling to our advantage 
● Automatically catch ValidationException(s)
EXCEPTIONS FOR DAYS 
● We can use Laravel’s own error-handling to our advantage 
● Automatically catch ValidationException(s) -> 
○ Render a response
EXCEPTIONS FOR DAYS 
● We can use Laravel’s own error-handling to our advantage 
● Automatically catch ValidationException(s) -> 
○ Render a response 
○ Be more awesome…. er.
App::error(function(ValidationException $exception) 
{ 
$errorResponse = [ 
‘message’ => $exception->getMessage(), 
‘errors’ => $exception->getErrors() 
]; 
return Response::json($errorResponse, $statusCode = 422); 
}
App::error(function(ValidationException $exception) 
{ 
$errorResponse = [ 
‘message’ => $exception->getMessage(), 
‘errors’ => $exception->getErrors() 
]; 
return Response::json($errorResponse, $statusCode = 422); 
}
App::error(function(ValidationException $exception) 
{ 
$errorResponse = [ 
‘message’ => $exception->getMessage(), 
‘errors’ => $exception->getErrors() 
]; 
return Response::json($errorResponse, $statusCode = 422); 
}
App::error(function(ValidationException $exception) 
{ 
$errorResponse = [ 
‘message’ => $exception->getMessage(), 
‘errors’ => $exception->getErrors() 
]; 
return Response::json($errorResponse, $statusCode = 422); 
}
TO CONCLUDE 
● We’ve setup validation as part of its own domain (it’s entirely responsible 
for nothing other than validation)
TO CONCLUDE 
● We’ve setup validation as part of its own domain (it’s entirely responsible 
for nothing other than validation) 
● We’ve freed our models from the additional weight of having to handle 
possibly very complex validation requirements.
TO CONCLUDE 
● We’ve setup validation as part of its own domain (it’s entirely responsible 
for nothing other than validation) 
● We’ve freed our models from the additional weight of having to handle 
possibly very complex validation requirements. 
● We’ve let Laravel handle our own errors - cleaning up our code!
TO CONCLUDE 
● We’ve setup validation as part of its own domain (it’s entirely responsible 
for nothing other than validation) 
● We’ve freed our models from the additional weight of having to handle 
possibly very complex validation requirements. 
● We’ve let Laravel handle our own errors - cleaning up our code! 
● Our validation is now much easier to extend, and implement (and move 
around)
// Instead of this... 
public function postRegister() 
{ 
$input = Input::get(); 
try { 
App::make(‘UserRegistrationValidation’, [$input])->validate(); 
} 
catch (ValidationException $e) { 
// Handle errors 
} 
// Create a response 
return User::create($input); 
}
// Now we have this. 
public function postRegister() 
{ 
$input = Input::get(); 
App::make(‘UserRegistrationValidation’, [$input])->validate(); 
return User::create($input); 
}
A FINAL POINT
A FINAL POINT 
● I’m still learning
A FINAL POINT 
● I’m still learning 
● Mitchell’s talk on Doctrine
A FINAL POINT 
● I’m still learning 
● Mitchell’s talk on Doctrine 
● Value objects could be interesting for validation requirements (Mathias?)
THANK YOU :)
THANK YOU :) 
● http://kirkbushell.me 
● https://github.com/kirkbushell 
● Talk comments/feedback: https://joind.in/talk/view/11690 
● @kirkbushell

Contenu connexe

En vedette

HOW TO PROCESS DATA IN VARIOUS GEO'S A COMPARATIVE ANALYSIS BY SANJEEV SINGH...
HOW TO PROCESS DATA IN VARIOUS GEO'S A  COMPARATIVE ANALYSIS BY SANJEEV SINGH...HOW TO PROCESS DATA IN VARIOUS GEO'S A  COMPARATIVE ANALYSIS BY SANJEEV SINGH...
HOW TO PROCESS DATA IN VARIOUS GEO'S A COMPARATIVE ANALYSIS BY SANJEEV SINGH...Sanjeev Bharwan
 
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)Sanjeev Bharwan
 
Introduction to data pre-processing and cleaning
Introduction to data pre-processing and cleaning Introduction to data pre-processing and cleaning
Introduction to data pre-processing and cleaning Matteo Manca
 
DataMeet 4: Data cleaning & census data
DataMeet 4: Data cleaning & census dataDataMeet 4: Data cleaning & census data
DataMeet 4: Data cleaning & census dataRitvvij Parrikh
 
Theory & Practice of Data Cleaning: Introduction to OpenRefine
Theory & Practice of Data Cleaning: Introduction to OpenRefineTheory & Practice of Data Cleaning: Introduction to OpenRefine
Theory & Practice of Data Cleaning: Introduction to OpenRefineBertram Ludäscher
 
Bba203 unit 2data processing concepts
Bba203   unit 2data processing conceptsBba203   unit 2data processing concepts
Bba203 unit 2data processing conceptskinjal patel
 
data warehousing & minining 1st unit
data warehousing & minining 1st unitdata warehousing & minining 1st unit
data warehousing & minining 1st unitbhagathk
 
Data Processing-Presentation
Data Processing-PresentationData Processing-Presentation
Data Processing-Presentationnibraspk
 
DATA PROCESSING CYCLE
DATA PROCESSING CYCLEDATA PROCESSING CYCLE
DATA PROCESSING CYCLEZaheer Abbasi
 

En vedette (13)

HOW TO PROCESS DATA IN VARIOUS GEO'S A COMPARATIVE ANALYSIS BY SANJEEV SINGH...
HOW TO PROCESS DATA IN VARIOUS GEO'S A  COMPARATIVE ANALYSIS BY SANJEEV SINGH...HOW TO PROCESS DATA IN VARIOUS GEO'S A  COMPARATIVE ANALYSIS BY SANJEEV SINGH...
HOW TO PROCESS DATA IN VARIOUS GEO'S A COMPARATIVE ANALYSIS BY SANJEEV SINGH...
 
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
 
Introduction to data pre-processing and cleaning
Introduction to data pre-processing and cleaning Introduction to data pre-processing and cleaning
Introduction to data pre-processing and cleaning
 
Data Cleaning
Data CleaningData Cleaning
Data Cleaning
 
DataMeet 4: Data cleaning & census data
DataMeet 4: Data cleaning & census dataDataMeet 4: Data cleaning & census data
DataMeet 4: Data cleaning & census data
 
Theory & Practice of Data Cleaning: Introduction to OpenRefine
Theory & Practice of Data Cleaning: Introduction to OpenRefineTheory & Practice of Data Cleaning: Introduction to OpenRefine
Theory & Practice of Data Cleaning: Introduction to OpenRefine
 
Bba203 unit 2data processing concepts
Bba203   unit 2data processing conceptsBba203   unit 2data processing concepts
Bba203 unit 2data processing concepts
 
data warehousing & minining 1st unit
data warehousing & minining 1st unitdata warehousing & minining 1st unit
data warehousing & minining 1st unit
 
Data processing cycle
Data processing cycleData processing cycle
Data processing cycle
 
Data cleansing
Data cleansingData cleansing
Data cleansing
 
Data processing
Data processingData processing
Data processing
 
Data Processing-Presentation
Data Processing-PresentationData Processing-Presentation
Data Processing-Presentation
 
DATA PROCESSING CYCLE
DATA PROCESSING CYCLEDATA PROCESSING CYCLE
DATA PROCESSING CYCLE
 

Similaire à Comprehensive Validation with Laravel 4

Introduction to atdd
Introduction to atddIntroduction to atdd
Introduction to atddShawn Wallace
 
Validation for APIs in Laravel 4
Validation for APIs in Laravel 4Validation for APIs in Laravel 4
Validation for APIs in Laravel 4Kirk Bushell
 
Standardizing and Managing Your Infrastructure - MOSC 2011
Standardizing and Managing Your Infrastructure - MOSC 2011Standardizing and Managing Your Infrastructure - MOSC 2011
Standardizing and Managing Your Infrastructure - MOSC 2011Brian Ritchie
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Steven Smith
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareChris Weldon
 
Improving the Design of Existing Software
Improving the Design of Existing SoftwareImproving the Design of Existing Software
Improving the Design of Existing SoftwareSteven Smith
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Leading the Transformation: Applying DevOps and Agile Principles at Scale
Leading the Transformation:  Applying DevOps and Agile Principles at ScaleLeading the Transformation:  Applying DevOps and Agile Principles at Scale
Leading the Transformation: Applying DevOps and Agile Principles at ScaleIBM UrbanCode Products
 
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...Adrian Jones
 
JustEnoughDevOpsForDataScientists
JustEnoughDevOpsForDataScientistsJustEnoughDevOpsForDataScientists
JustEnoughDevOpsForDataScientistsAnya Bida
 
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...Texavi Innovative Solutions
 
DevOps/Flow workshop for agile india 2015
DevOps/Flow workshop for agile india 2015DevOps/Flow workshop for agile india 2015
DevOps/Flow workshop for agile india 2015Yuval Yeret
 
Agile Software Development at UPT DEGI | Nov, 2015
Agile Software Development at UPT DEGI | Nov, 2015Agile Software Development at UPT DEGI | Nov, 2015
Agile Software Development at UPT DEGI | Nov, 2015Eduardo Ribeiro
 
Scaling agile without the scaling framework
Scaling agile without the scaling frameworkScaling agile without the scaling framework
Scaling agile without the scaling frameworkagilebydesign
 
Continuous delivery is more than dev ops
Continuous delivery is more than dev opsContinuous delivery is more than dev ops
Continuous delivery is more than dev opsAgile Montréal
 
Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org - Dev...
Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org -  Dev...Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org -  Dev...
Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org - Dev...DevOpsDays Tel Aviv
 

Similaire à Comprehensive Validation with Laravel 4 (20)

Introduction to atdd
Introduction to atddIntroduction to atdd
Introduction to atdd
 
Validation for APIs in Laravel 4
Validation for APIs in Laravel 4Validation for APIs in Laravel 4
Validation for APIs in Laravel 4
 
Standardizing and Managing Your Infrastructure - MOSC 2011
Standardizing and Managing Your Infrastructure - MOSC 2011Standardizing and Managing Your Infrastructure - MOSC 2011
Standardizing and Managing Your Infrastructure - MOSC 2011
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016
 
Orchestration, the conductor's score
Orchestration, the conductor's scoreOrchestration, the conductor's score
Orchestration, the conductor's score
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver Software
 
Improving the Design of Existing Software
Improving the Design of Existing SoftwareImproving the Design of Existing Software
Improving the Design of Existing Software
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Leading the Transformation: Applying DevOps and Agile Principles at Scale
Leading the Transformation:  Applying DevOps and Agile Principles at ScaleLeading the Transformation:  Applying DevOps and Agile Principles at Scale
Leading the Transformation: Applying DevOps and Agile Principles at Scale
 
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
 
JustEnoughDevOpsForDataScientists
JustEnoughDevOpsForDataScientistsJustEnoughDevOpsForDataScientists
JustEnoughDevOpsForDataScientists
 
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
 
Introduction to AngularJs
Introduction to AngularJsIntroduction to AngularJs
Introduction to AngularJs
 
DevOps/Flow workshop for agile india 2015
DevOps/Flow workshop for agile india 2015DevOps/Flow workshop for agile india 2015
DevOps/Flow workshop for agile india 2015
 
Agile Software Development at UPT DEGI | Nov, 2015
Agile Software Development at UPT DEGI | Nov, 2015Agile Software Development at UPT DEGI | Nov, 2015
Agile Software Development at UPT DEGI | Nov, 2015
 
Scaling agile without the scaling framework
Scaling agile without the scaling frameworkScaling agile without the scaling framework
Scaling agile without the scaling framework
 
Continuous delivery is more than dev ops
Continuous delivery is more than dev opsContinuous delivery is more than dev ops
Continuous delivery is more than dev ops
 
Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org - Dev...
Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org -  Dev...Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org -  Dev...
Real-Time Metrics and Distributed Monitoring - Jeff Pierce, Change.org - Dev...
 

Dernier

Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shardsChristopher Curtin
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 

Dernier (20)

Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards2024 DevNexus Patterns for Resiliency: Shuffle shards
2024 DevNexus Patterns for Resiliency: Shuffle shards
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 

Comprehensive Validation with Laravel 4

  • 1. COMPREHENSIVE VALIDATION WITH LARAVEL 4 Kirk Bushell
  • 2. INTRODUCTION ● Developer - 15 years experience ● Technical lead - Tectonic Digital ● Software architect - Award Force - http://awardforce.com ● Information Technologies Coordinator - Engineers without Borders ● Technical writer - http://kirkbushell.me ● Talk comments/feedback: https://joind.in/talk/view/11690 ● Github - https://github.com/kirkbushell
  • 3. “ALWAYS PASS ON WHAT YOU LEARN”
  • 4. “ALWAYS PASS ON WHAT YOU LEARN” - YODA
  • 5. WHY CARE ABOUT VALIDATION?
  • 6. WHY CARE ABOUT VALIDATION? ● Validation can get messy - really quick
  • 7. WHY CARE ABOUT VALIDATION? ● Validation can get messy - really quick ● We do it. All the time.
  • 8. WHY CARE ABOUT VALIDATION? ● Validation can get messy - really quick ● We do it. All the time. ● Lots of architectural discussion in the community
  • 9. INSPIRATION ● What started this thought process?
  • 10. INSPIRATION ● What started this thought process? ● Jeffrey Way’s twitter post earlier this year about where people put their validation rules.
  • 11. INSPIRATION ● What started this thought process? ● Jeffrey Way’s twitter post earlier this year about where people put their validation rules. ● Jason Lewis’ article on advanced validation: http://jasonlewis. me/article/laravel-advanced-validation
  • 12. INSPIRATION ● What started this thought process? ● Jeffrey Way’s twitter post earlier this year about where people put their validation rules. ● Jason Lewis’ article on advanced validation: http://jasonlewis. me/article/laravel-advanced-validation ● Lots of posts about validation on forums, twitter.etc.
  • 13. BUT FIRST, A FEW POINTS
  • 14. BUT FIRST, A FEW POINTS ● This approach is best suited to medium-large applications
  • 15. BUT FIRST, A FEW POINTS ● This approach is best suited to medium-large applications ● We’re going to use “users” as a set of use-cases to demonstrate this approach and style to the handling of validation
  • 16. BUT FIRST, A FEW POINTS ● This approach is best suited to medium-large applications ● We’re going to use “users” as a set of use-cases to demonstrate this approach and style to the handling of validation ● There will be a little code
  • 17. BUT FIRST, A FEW POINTS ● This approach is best suited to medium-large applications ● We’re going to use “users” as a set of use-cases to demonstrate this approach and style to the handling of validation ● There will be a little code (Sorry)
  • 18. WHAT WILL WE COVER
  • 19. WHAT WILL WE COVER ● A brief history of MVC (to provide context)
  • 20. WHAT WILL WE COVER ● A brief history of MVC (to provide context) ● Good validation practice (resource vs use-case)
  • 21. WHAT WILL WE COVER ● A brief history of MVC (to provide context) ● Good validation practice (resource vs use-case) ● How to architect your validation rules so that they can grow, adhering to SOLID design principles
  • 22. WHAT WILL WE COVER ● A brief history of MVC (to provide context) ● Good validation practice (resource vs use-case) ● How to architect your validation rules so that they can grow, adhering to SOLID design principles ● Where validation should go (controllers, models, repositories - where?)
  • 23. WHAT WILL WE COVER ● A brief history of MVC (to provide context) ● Good validation practice (resource vs use-case) ● How to architect your validation rules so that they can grow, adhering to SOLID design principles ● Where validation should go (controllers, models, repositories - where?) ● Use exceptions to alter program flow and provide greater readability
  • 24. ASSUMPTIONS ● You know a thing or two about Laravel 4’s validation functionality
  • 25. ASSUMPTIONS ● You know a thing or two about Laravel 4’s validation functionality ● You understand how to use Laravel’s IoC features
  • 26. ASSUMPTIONS ● You know a thing or two about Laravel 4’s validation functionality ● You understand how to use Laravel’s IoC features ● You understand the importance of a separation of concerns (if not, we’ll cover this a little)
  • 27. ASSUMPTIONS ● You know a thing or two about Laravel 4’s validation functionality ● You understand how to use Laravel’s IoC features ● You understand the importance of a separation of concerns (if not, we’ll cover this a little) ● You’ve dealt with growing validation concerns before (or not)
  • 28. A BRIEF HISTORY OF MVC
  • 29. A BRIEF HISTORY OF MVC ● No one knew
  • 30. A BRIEF HISTORY OF MVC ● No one knew ● Fat controllers
  • 31. A BRIEF HISTORY OF MVC ● No one knew ● Fat controllers ● Skinny controllers, fat models
  • 32. A BRIEF HISTORY OF MVC ● No one knew ● Fat controllers ● Skinny controllers, fat models ● Hexagonal architecture (service layers)
  • 33. A BRIEF HISTORY OF MVC ● No one knew ● Fat controllers ● Skinny controllers, fat models ● Hexagonal architecture (service layers) ● Repositories
  • 34. A BRIEF HISTORY OF MVC ● No one knew ● Fat controllers ● Skinny controllers, fat models ● Hexagonal architecture (service layers) ● Repositories ● Validation?
  • 36. THE REPOSITORY PATTERN ● Why? ● Helped clean up models
  • 37. THE REPOSITORY PATTERN ● Why? ● Helped clean up models ● Ensured a common interface for establishing data storage access
  • 38. THE REPOSITORY PATTERN ● Why? ● Helped clean up models ● Ensured a common interface for establishing data storage access ● Enabled us to easily swap out storage formats, caching mechanisms and more…
  • 39. THE REPOSITORY PATTERN ● Why? ● Helped clean up models ● Ensured a common interface for establishing data storage access ● Enabled us to easily swap out storage formats, caching mechanisms and more… ● What about validation?
  • 40. WHY NOT ON THE MODEL? ● Breaks the Single Responsibility Principle
  • 41. WHY NOT ON THE MODEL? ● Breaks the Single Responsibility Principle ● Makes no sense if you’re using repositories
  • 42. WHY NOT ON THE MODEL? ● Breaks the Single Responsibility Principle ● Makes no sense if you’re using repositories ● Should be called as part of the service layer
  • 43. WHY NOT ON THE MODEL? ● Breaks the Single Responsibility Principle ● Makes no sense if you’re using repositories ● Should be called as part of the service layer ● Validation is its own domain of logic
  • 44. WHY NOT ON THE MODEL? ● Breaks the Single Responsibility Principle ● Makes no sense if you’re using repositories ● Should be called as part of the service layer ● Validation is its own domain of logic ● I don’t like model-based validation… it smells.
  • 45. WHY NOT ON THE MODEL? ● Breaks the Single Responsibility Principle ● Makes no sense if you’re using repositories ● Should be called as part of the service layer ● Validation is its own domain of logic ● I don’t like model-based validation… it smells. ● But kirk… why?
  • 46. HOW I VIEW MODELS ● Our models are already a mess of various responsibilities
  • 47. HOW I VIEW MODELS ● Our models are already a mess of various responsibilities ● What table or collection to talk to
  • 48. HOW I VIEW MODELS ● Our models are already a mess of various responsibilities ● What table or collection to talk to ● Relationships
  • 49. HOW I VIEW MODELS ● Our models are already a mess of various responsibilities ● What table or collection to talk to ● Relationships ● Querying
  • 50. HOW I VIEW MODELS ● Our models are already a mess of various responsibilities ● What table or collection to talk to ● Relationships ● Querying ● All part of active record. Validation isn’t.
  • 51. HOW I VIEW MODELS ● Our models are already a mess of various responsibilities ● What table or collection to talk to ● Relationships ● Querying ● All part of active record. Validation isn’t. ● They can (and arguably - should) be used as schema descriptors for your application
  • 52. class User extends Eloquent { public $rules = [ ‘name’ => [‘required’, ‘min:8’], ‘address’ => ‘required’ ]; public function save() { $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new Exception(‘Ugh, y u no provide good datums!?’); return parent::save(); } }
  • 53. class User extends Eloquent { public $rules = [ ‘name’ => [‘required’, ‘min:8’], ‘address’ => ‘required’ ]; public function save() { $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new Exception(‘Ugh, y u no provide good datums!?’); return parent::save(); } }
  • 54. class User extends Eloquent { public $rules = [ ‘name’ => [‘required’, ‘min:8’], ‘address’ => ‘required’ ]; public function save() { $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new Exception(‘Ugh, y u no provide good datums!?’); return parent::save(); } }
  • 55. class User extends Eloquent { public $rules = [ ‘name’ => [‘required’, ‘min:8’], ‘address’ => ‘required’ ]; public function save() { $validator = Validator::make($this->getAttributes(), $this->rules); if (!$validator->fails()) throw new Exception(‘Ugh, y u no provide good datums!?’); return parent::save(); } }
  • 56. BUT… CAN WE DO BETTER?
  • 58. OF COURSE WE CAN ;)
  • 59. A CUSTOM VALIDATOR ● Defines an approach to handle validation use-cases
  • 60. A CUSTOM VALIDATOR ● Defines an approach to handle validation use-cases ● Easier to use and read in our code
  • 61. A CUSTOM VALIDATOR ● Defines an approach to handle validation use-cases ● Easier to use and read in our code ● Provides the ability to automatically handle validation errors
  • 62. A CUSTOM VALIDATOR ● Defines an approach to handle validation use-cases ● Easier to use and read in our code ● Provides the ability to automatically handle validation errors ● Wraps Laravel’s validator so we’re not reinventing the wheel
  • 63. A CUSTOM VALIDATOR ● Defines an approach to handle validation use-cases ● Easier to use and read in our code ● Provides the ability to automatically handle validation errors ● Wraps Laravel’s validator so we’re not reinventing the wheel ● Inspired by Jason Lewis’ validator (originally based on L3): http://jasonlewis.me/article/laravel-advanced-validation
  • 64. abstract class Validation { protected $rules = []; protected $messages = []; protected $input = []; public function __construct(array $input = []) { $this->input = $input; } public function validate() { $rules = $this->getRules(); $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new ValidationException($validator);
  • 65. abstract class Validation { protected $rules = []; protected $messages = []; protected $input = []; public function __construct(array $input = []) { $this->input = $input; } public function validate() { $rules = $this->getRules(); $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new ValidationException($validator);
  • 66. abstract class Validation { protected $rules = []; protected $messages = []; protected $input = []; public function __construct(array $input = []) { $this->input = $input; } public function validate() { $rules = $this->getRules(); $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new ValidationException($validator);
  • 67. abstract class Validation { protected $rules = []; protected $messages = []; protected $input = []; public function __construct(array $input = []) { $this->input = $input; } public function validate() { $rules = $this->getRules(); $validator = Validator::make($this->getInput(), $this->rules); if ($validator->fails()) throw new ValidationException($validator);
  • 68. abstract class Validation { public function validate() { $rules = $this->getRules(); $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new ValidationException($validator); } public function getRules() { return $this->rules; } }
  • 69. abstract class Validation { public function getRules() { return $this->rules; } public function getInput() { return $this->input; } }
  • 70. abstract class Validation { public function validate() { $rules = $this->getRules(); $validator = Validator::make($this->getAttributes(), $this->rules); if ($validator->fails()) throw new ValidationException($validator); } public function getRules() { return $this->rules; } }
  • 71. class ValidationException extends Exception { public function __construct(Validator $validator) { $this->message = 'Validation has failed, or something.'; $this->validator = $validator; } public function getErrors() { return $this->validator->messages(); }
  • 72. class ValidationException extends Exception { public function __construct(Validator $validator) { $this->message = 'Validation has failed, or something.'; $this->validator = $validator; } public function getErrors() { return $this->validator->messages(); }
  • 73. class ValidationException extends Exception { public function __construct(Validator $validator) { $this->message = 'Validation has failed, or something.'; $this->validator = $validator; } public function getErrors() { return $this->validator->messages(); }
  • 74. A VALIDATION USE-CASE ● User registration (everyone loves registration… right?)
  • 75. A VALIDATION USE-CASE ● User registration (everyone loves registration… right?) ● We’ll need to define a validator specific to this requirement
  • 76. A VALIDATION USE-CASE ● User registration (everyone loves registration… right?) ● We’ll need to define a validator specific to this requirement ● Let’s go with the usual:
  • 77. A VALIDATION USE-CASE ● User registration (everyone loves registration… right?) ● We’ll need to define a validator specific to this requirement ● Let’s go with the usual: ○ Username
  • 78. A VALIDATION USE-CASE ● User registration (everyone loves registration… right?) ● We’ll need to define a validator specific to this requirement ● Let’s go with the usual: ○ Username ○ Email address
  • 79. A VALIDATION USE-CASE ● User registration (everyone loves registration… right?) ● We’ll need to define a validator specific to this requirement ● Let’s go with the usual: ○ Username ○ Email address ○ Password
  • 80. class UserRegistrationValidation extends Validation { protected $rules = [ ‘username’ => [‘required’, ‘min:3’], ‘email’ => [‘required’, ‘email’], ‘password’ => [‘required’, ‘min:8’] ]; }
  • 81. class UserRegistrationValidation extends Validation { public function getRules() { $rules = [ ‘username’ => [‘required’, ‘min:3’], ‘email’ => [‘required’, ‘email’], ‘password’ => [‘required’, ‘min:8’] ]; return $rules; } }
  • 82. SO… HOW DO WE USE THIS? ● Utilise our validation for user registration
  • 83. SO… HOW DO WE USE THIS? ● Utilise our validation for user registration ● Provide it with the required $input (in this case, probably Input::get())
  • 84. SO… HOW DO WE USE THIS? ● Utilise our validation for user registration ● Provide it with the required $input (in this case, probably Input::get()) ● Then call the validate function
  • 85. SO… HOW DO WE USE THIS? ● Utilise our validation for user registration ● Provide it with the required $input (in this case, probably Input::get()) ● Then call the validate function ● Handle the onslaught of errors!
  • 86. SO… HOW DO WE USE THIS? ● Utilise our validation for user registration ● Provide it with the required $input (in this case, probably Input::get()) ● Then call the validate function ● Handle the onslaught of errors! ● Let’s see an example, shall we?
  • 87. // UserController public function postRegister() { $input = Input::get(); try { App::make(‘UserRegistrationValidation’, [$input])->validate(); } catch (ValidationException $e) { // Handle errors } // Create a response return User::create($input); }
  • 90. AND LARAVEL CAN HELP :)
  • 91. EXCEPTIONS FOR DAYS ● We can use Laravel’s own error-handling to our advantage
  • 92. EXCEPTIONS FOR DAYS ● We can use Laravel’s own error-handling to our advantage ● Automatically catch ValidationException(s)
  • 93. EXCEPTIONS FOR DAYS ● We can use Laravel’s own error-handling to our advantage ● Automatically catch ValidationException(s) -> ○ Render a response
  • 94. EXCEPTIONS FOR DAYS ● We can use Laravel’s own error-handling to our advantage ● Automatically catch ValidationException(s) -> ○ Render a response ○ Be more awesome…. er.
  • 95. App::error(function(ValidationException $exception) { $errorResponse = [ ‘message’ => $exception->getMessage(), ‘errors’ => $exception->getErrors() ]; return Response::json($errorResponse, $statusCode = 422); }
  • 96. App::error(function(ValidationException $exception) { $errorResponse = [ ‘message’ => $exception->getMessage(), ‘errors’ => $exception->getErrors() ]; return Response::json($errorResponse, $statusCode = 422); }
  • 97. App::error(function(ValidationException $exception) { $errorResponse = [ ‘message’ => $exception->getMessage(), ‘errors’ => $exception->getErrors() ]; return Response::json($errorResponse, $statusCode = 422); }
  • 98. App::error(function(ValidationException $exception) { $errorResponse = [ ‘message’ => $exception->getMessage(), ‘errors’ => $exception->getErrors() ]; return Response::json($errorResponse, $statusCode = 422); }
  • 99. TO CONCLUDE ● We’ve setup validation as part of its own domain (it’s entirely responsible for nothing other than validation)
  • 100. TO CONCLUDE ● We’ve setup validation as part of its own domain (it’s entirely responsible for nothing other than validation) ● We’ve freed our models from the additional weight of having to handle possibly very complex validation requirements.
  • 101. TO CONCLUDE ● We’ve setup validation as part of its own domain (it’s entirely responsible for nothing other than validation) ● We’ve freed our models from the additional weight of having to handle possibly very complex validation requirements. ● We’ve let Laravel handle our own errors - cleaning up our code!
  • 102. TO CONCLUDE ● We’ve setup validation as part of its own domain (it’s entirely responsible for nothing other than validation) ● We’ve freed our models from the additional weight of having to handle possibly very complex validation requirements. ● We’ve let Laravel handle our own errors - cleaning up our code! ● Our validation is now much easier to extend, and implement (and move around)
  • 103. // Instead of this... public function postRegister() { $input = Input::get(); try { App::make(‘UserRegistrationValidation’, [$input])->validate(); } catch (ValidationException $e) { // Handle errors } // Create a response return User::create($input); }
  • 104. // Now we have this. public function postRegister() { $input = Input::get(); App::make(‘UserRegistrationValidation’, [$input])->validate(); return User::create($input); }
  • 106. A FINAL POINT ● I’m still learning
  • 107. A FINAL POINT ● I’m still learning ● Mitchell’s talk on Doctrine
  • 108. A FINAL POINT ● I’m still learning ● Mitchell’s talk on Doctrine ● Value objects could be interesting for validation requirements (Mathias?)
  • 110. THANK YOU :) ● http://kirkbushell.me ● https://github.com/kirkbushell ● Talk comments/feedback: https://joind.in/talk/view/11690 ● @kirkbushell