validation for apis in laravel 4
DESCRIPTION
In my first talk, I raise the concerns I have with current validation practises and what we can do to make it better.TRANSCRIPT
Validation for APIsGood validation practises. API focused.
Kirk Bushell
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
Disclaimers
This is my first talk.
Sorry.
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)
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
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
What I'm not going to talk about
• RESTful APIs
• The view layer
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.
Introducing.. the repository pattern?
• Helped clean up models
• Query building and object management
• So, what about validation?
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)
Implementing validation
The validate method
Please read Jason Lewis' article: http://jasonlewis.me/article/laravel-advanced-validation
// Validate function from articleprotected function validate(){ $this->validator = Validator::make($this->input, $this->rules);
if ($this->validator->fails()) { throw new ValidateException($this->validator); }}
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(); }}
Our code, our rules
Implement our own custom rules for user registration:
// UserValidator classclass UserValidator extends Validator{ public function register() { $this->rules = [ 'email' => ['required', 'email'], 'password' => ['required'] ];
$this->validate(); }}
Validate!
Within our controller, load up our validator and validate the input.
// UserControllerpublic function postRegister(){ $input = Input::get();
App::make('UserValidator', [$input])->register();
return User::create($input);}
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.
Laravel 4 error handling
Create an error handler that is specific to validation exceptions:
App::error(function(ValidateException $exception){ $errorResponse = [ 'message' => $exception->getMessage(), 'errors' => $exception->getErrors() ];
return Response::json($errorResponse, 422); // Unprocessable entity});
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)
Thank you.
You can catch me at the following online locales:
• http://kirkbushell.me
• http://github.com/kirkbushell
• @kirkbushell