2. Who the hell am I?
Technical Lead for Tectonic Digital (www.tectonic.com.au)
Software architect for http://awardforce.com
Technical writer (see: http://kirkbushell.me)
Open source contributor (Laravel 3/4, various other projects)
http://github.com/kirkbushell
Also known as Oddman on IRC, forums.etc.
@kirkbushell
6. In addition...
I'll assume you know a couple of things about validation and
You know or at least understand some of the concepts of Laravel
4, including:
Dependency injection and
The IoC feature
I start work at 4.30am (apologies if I'm not quite with it)
7. Why?
There's been a lot of talk in the community the last 6 months
about validation
How we can do it well - lots of different opinions
I have a pretty strong opinion on this matter
8. What we're going to cover
A brief history of MVC, the repository pattern and why validation
should be its own domain
Implementing validation within an API context
Using exceptions for greater readability
Catching exceptions to generate API responses automagically
The end result - cleaner code
9. What I'm not going to talk about
RESTful APIs
The view layer
10. A brief history of everything MVC.
A blessing to web development (and software development in
general)
Fat controllers, skinny models
Skinny controllers, fat models
Validation tied up in models (along with everything else)
We still seem to be stuck on the previous point.
11. Introducing.. the repository pattern?
Helped clean up models
Query building and object management
So, what about validation?
12. Validate all the things!
Validation within models breaks the single responsibility principle
Validation in models doesn't make much sense if you're using the
repository pattern
Implemented via the controller or a service (such as a user
registration service)
14. The validate method
Please read Jason Lewis' article: http://jasonlewis.me/article/laravel-
advanced-validation
// Validate function from article
protected function validate()
{
$this->validator = Validator::make($this->input, $this->rules);
if ($this->validator->fails())
{
throw new ValidateException($this->validator);
}
}
15. ValidateException
class ValidateException extends Exception
{
protected $validator;
public function __construct(Validator $validator)
{
$this->message = 'Validation has failed, or something.';
$this->validator = $validator;
}
public function getErrors()
{
return $this->validator->messages();
}
}
16. Our code, our rules
Implement our own custom rules for user registration:
// UserValidator class
class UserValidator extends Validator
{
public function register()
{
$this->rules = [
'email' => ['required', 'email'],
'password' => ['required']
];
$this->validate();
}
}
17. Validate!
Within our controller, load up our validator and validate the input.
// UserController
public function postRegister()
{
$input = Input::get();
App::make('UserValidator', [$input])->register();
return User::create($input);
}
18. Now what?
When validation fails it will throw an exception:
if ($this->validator->fails())
{
throw new ValidateException($this->validator);
}
We need to catch that exception and return a nice status code and
error message, along with any validation errors.
Laravel 4 provides an excellent way of managing this.
19. Laravel 4 error handling
Create an error handler that is speci鍖c to validation exceptions:
App::error(function(ValidateException $exception)
{
$errorResponse = [
'message' => $exception->getMessage(),
'errors' => $exception->getErrors()
];
return Response::json($errorResponse, 422); // Unprocessable entity
});
20. In conclusion
Complex validation should be in its own domain
Helps to clean up our code, making it more readable
Let the framework handle exceptions for you!
Best for large applications (not so applicable to small apps)