SlideShare a Scribd company logo
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)

PDF
Validation for APIs in Laravel 4
PPTX
Crafting beautiful software
PPTX
Building Large Scale PHP Web Applications with Laravel 4
PDF
Symfony2 validation
PDF
Does your code spark joy? Refactoring techniques to make your life easier.
PPTX
Refactoring Workflows & Techniques Presentation by Valentin Stantescu
PPTX
Fluent validation
PPTX
Software Development with PHP & Laravel
PDF
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
PDF
Be pragmatic, be SOLID
PDF
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
KEY
Building Better Applications with Data::Manager
PDF
What NOT to test in your project
PDF
Spring 3: What's New
PDF
Clean code & design patterns
PPTX
Tidy Up Your Code
PDF
Refactoring Legacy Code
PDF
Unbreakable Domain Models PHPUK 2014 London
ODP
Introduction to Domain-Driven Design
PPTX
Eloquent workflow: delivering data from database to client in a right way
Validation for APIs in Laravel 4
Crafting beautiful software
Building Large Scale PHP Web Applications with Laravel 4
Symfony2 validation
Does your code spark joy? Refactoring techniques to make your life easier.
Refactoring Workflows & Techniques Presentation by Valentin Stantescu
Fluent validation
Software Development with PHP & Laravel
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
Building Better Applications with Data::Manager
What NOT to test in your project
Spring 3: What's New
Clean code & design patterns
Tidy Up Your Code
Refactoring Legacy Code
Unbreakable Domain Models PHPUK 2014 London
Introduction to Domain-Driven Design
Eloquent workflow: delivering data from database to client in a right way
Ad

Recently uploaded (20)

PPTX
ai tools demonstartion for schools and inter college
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
top salesforce developer skills in 2025.pdf
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Designing Intelligence for the Shop Floor.pdf
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Introduction to Artificial Intelligence
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
ai tools demonstartion for schools and inter college
Upgrade and Innovation Strategies for SAP ERP Customers
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
top salesforce developer skills in 2025.pdf
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Which alternative to Crystal Reports is best for small or large businesses.pdf
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Designing Intelligence for the Shop Floor.pdf
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
VVF-Customer-Presentation2025-Ver1.9.pptx
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Wondershare Filmora 15 Crack With Activation Key [2025
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
How to Choose the Right IT Partner for Your Business in Malaysia
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Introduction to Artificial Intelligence
Navsoft: AI-Powered Business Solutions & Custom Software Development
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx

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