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

More Related Content

PDF
XebiCon'17 : //Tam-tams// Voici l’histoire de la disparition des dinosaures d...
PDF
CI doesn’t start with Jenkins
PPTX
Agile Seminar at Politecnico di Milano
PDF
[QaOps] Continuouss Integration | Pipeline strategy
PDF
Testing and Software Writer a year later
PDF
TDD with Puppet Tutorial presented at Cascadia IT Conference 2014-03-07
PDF
Ruby onrails cucumber-rspec-capybara
PDF
7 tools for your devops stack
XebiCon'17 : //Tam-tams// Voici l’histoire de la disparition des dinosaures d...
CI doesn’t start with Jenkins
Agile Seminar at Politecnico di Milano
[QaOps] Continuouss Integration | Pipeline strategy
Testing and Software Writer a year later
TDD with Puppet Tutorial presented at Cascadia IT Conference 2014-03-07
Ruby onrails cucumber-rspec-capybara
7 tools for your devops stack

Viewers also liked (13)

PPTX
HOW TO PROCESS DATA IN VARIOUS GEO'S A COMPARATIVE ANALYSIS BY SANJEEV SINGH...
PPTX
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
PPTX
Introduction to data pre-processing and cleaning
PPT
DataMeet 4: Data cleaning & census data
PPT
Theory & Practice of Data Cleaning: Introduction to OpenRefine
PPTX
Bba203 unit 2data processing concepts
PPT
data warehousing & minining 1st unit
PPTX
Data processing cycle
PPTX
Data cleansing
PDF
Data processing
PPT
Data Processing-Presentation
PPT
DATA PROCESSING CYCLE
HOW TO PROCESS DATA IN VARIOUS GEO'S A COMPARATIVE ANALYSIS BY SANJEEV SINGH...
HIPPA COMPLIANCE (SANJEEV.S.BHARWAN)
Introduction to data pre-processing and cleaning
DataMeet 4: Data cleaning & census data
Theory & Practice of Data Cleaning: Introduction to OpenRefine
Bba203 unit 2data processing concepts
data warehousing & minining 1st unit
Data processing cycle
Data cleansing
Data processing
Data Processing-Presentation
DATA PROCESSING CYCLE
Ad

Similar to Comprehensive Validation with Laravel 4 (20)

KEY
Introduction to atdd
PDF
Validation for APIs in Laravel 4
KEY
Standardizing and Managing Your Infrastructure - MOSC 2011
PPTX
Improving the Quality of Existing Software
PPTX
Improving the Quality of Existing Software
PPTX
Improving the Quality of Existing Software - DevIntersection April 2016
PPTX
Orchestration, the conductor's score
KEY
Beyond TDD: Enabling Your Team to Continuously Deliver Software
PPTX
Improving the Design of Existing Software
PPTX
Improving the Quality of Existing Software
PDF
Leading the Transformation: Applying DevOps and Agile Principles at Scale
PPTX
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
PPTX
JustEnoughDevOpsForDataScientists
PPTX
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
PPTX
Introduction to AngularJs
PDF
DevOps/Flow workshop for agile india 2015
PDF
Agile Software Development at UPT DEGI | Nov, 2015
PPTX
Scaling agile without the scaling framework
PPTX
All you need is fast feedback loop, fast feedback loop, fast feedback loop is...
PDF
Continuous delivery is more than dev ops
Introduction to atdd
Validation for APIs in Laravel 4
Standardizing and Managing Your Infrastructure - MOSC 2011
Improving the Quality of Existing Software
Improving the Quality of Existing Software
Improving the Quality of Existing Software - DevIntersection April 2016
Orchestration, the conductor's score
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Improving the Design of Existing Software
Improving the Quality of Existing Software
Leading the Transformation: Applying DevOps and Agile Principles at Scale
The Agile Drupalist - Methodologies & Techniques for Running Effective Drupal...
JustEnoughDevOpsForDataScientists
All about Agile, an Overview - Texavi Tech Bootcamp on How to be agile- Texav...
Introduction to AngularJs
DevOps/Flow workshop for agile india 2015
Agile Software Development at UPT DEGI | Nov, 2015
Scaling agile without the scaling framework
All you need is fast feedback loop, fast feedback loop, fast feedback loop is...
Continuous delivery is more than dev ops
Ad

Recently uploaded (20)

PPTX
ESDS_SAP Application Cloud Offerings.pptx
PDF
Enscape 3D Crack + With 2025 Activation Key free
PDF
Module 1 - Introduction to Generative AI.pdf
PDF
OpenEXR Virtual Town Hall - August 2025
PPTX
Independent Consultants’ Biggest Challenges in ERP Projects – and How Apagen ...
PPTX
FLIGHT TICKET API | API INTEGRATION PLATFORM
PDF
Top AI Tools for Project Managers: My 2025 AI Stack
PPTX
Post-Migration Optimization Playbook: Getting the Most Out of Your New Adobe ...
PPTX
Presentation - Summer Internship at Samatrix.io_template_2.pptx
PDF
SBOM Document Quality Guide - OpenChain SBOM Study Group
PDF
C language slides for c programming book by ANSI
PDF
Difference Between Website and Web Application.pdf
PPTX
Greedy best-first search algorithm always selects the path which appears best...
PDF
Mobile App for Guard Tour and Reporting.pdf
PPT
introduction of sql, sql commands(DD,DML,DCL))
PDF
solman-7.0-ehp1-sp21-incident-management
PDF
OpenImageIO Virtual Town Hall - August 2025
PDF
Ragic Data Security Overview: Certifications, Compliance, and Network Safegua...
PPTX
Advanced Heap Dump Analysis Techniques Webinar Deck
PDF
Canva Desktop App With Crack Free Download 2025?
ESDS_SAP Application Cloud Offerings.pptx
Enscape 3D Crack + With 2025 Activation Key free
Module 1 - Introduction to Generative AI.pdf
OpenEXR Virtual Town Hall - August 2025
Independent Consultants’ Biggest Challenges in ERP Projects – and How Apagen ...
FLIGHT TICKET API | API INTEGRATION PLATFORM
Top AI Tools for Project Managers: My 2025 AI Stack
Post-Migration Optimization Playbook: Getting the Most Out of Your New Adobe ...
Presentation - Summer Internship at Samatrix.io_template_2.pptx
SBOM Document Quality Guide - OpenChain SBOM Study Group
C language slides for c programming book by ANSI
Difference Between Website and Web Application.pdf
Greedy best-first search algorithm always selects the path which appears best...
Mobile App for Guard Tour and Reporting.pdf
introduction of sql, sql commands(DD,DML,DCL))
solman-7.0-ehp1-sp21-incident-management
OpenImageIO Virtual Town Hall - August 2025
Ragic Data Security Overview: Certifications, Compliance, and Network Safegua...
Advanced Heap Dump Analysis Techniques Webinar Deck
Canva Desktop App With Crack Free Download 2025?

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