Pajama: Client and Server Validation Simplified
When implementing an HTML form that requires validation, a developer must make a decision: should I use client-side validation, server-side validation, or both?
In this article I will give a quick overview of the pros and cons of these validation techniques, as well as introduce my solution to the problem: Pajama.
Client-side Validation
Performing validation on the client has the advantage of being responsive to the user, as the data can be validated without communicating with the server.
On the other hand, client-side validation has the enormous disadvantage in that it cannot be trusted by the server. The client is in total control of what is being sent, meaning there is no way for a developer to guarantee that the browser is sending valid data. As a result, client-side validation must be combined with some sort of server-side validation in order to ensure the client isn't tampering with the data.
Server-side Validation
With that in mind, server-side validation seems like a much better solution. Since there are no trust issues with server-side validation, a developer has the option of foregoing client-side validation altogether.
Unfortunately, server-side validation has the downside that every time the client attempts validation, the entire form must be sent to the server. Worse yet, with some server-side validation schemes, all that data must then be sent back to the client and re-rendered if validation fails. This can happen several times for a single form leading to a significant amount of wasted bandwidth, especially for high-traffic sites.
Hybrid Validation
This brings us to hybrid validation. Under this validation scheme, data is first validated by the client. Once the client is satisfied the data is valid, it is then sent to the server and re-validated. This allows a form to have the responsiveness and efficiency of client-side validation with the trust of server-side validation. If a client tampers with the data before it is sent, the server-side validation will catch it.
Hybrid validation isn't without it's own drawbacks, however. Unlike client- or server-side validation, hybrid validation takes place in two different spots: the browser and the server. This adds to the implementation complexity. Complicating matters further, the client and server typically do not use the same programming language. This leads to a lot of questions: How do we validate the same way on client and server? Do we need to define our rules twice, once in JavaScript and once in the other language? What happens if the rules need to change? Do we have to remember to update the rules in both languages each time? What if each language has a different validation engine? Do I need to learn both?
This is where Pajama comes in.
Pajama
Pajama is a model validator written in PHP. It uses the same rule system as the popular jQuery Validation plugin and has a similar API. For example, here is how a validator is setup with the jQuery Validation plugin:
$("form").validate({
rules: {
first_name: "required",
last_name: "required"
},
submitHandler: function() {
$.post(...);
}
});
...and here's how it's setup in Pajama:
\Pajama\Validator::validate(array(
'model' => $_POST,
'rules' => array(
'first_name' => 'required',
'last_name' => 'required',
),
'validHandler' => function() {
// Store in database.
},
));
Notice the similarities in the API. If someone knows how to use the jQuery Validation plugin, they'll have a good idea of how to use Pajama.
Also notice how the rules are defined. Except for the differences in language syntax (i.e. { foo: "bar" }
versus array('foo' => 'bar')
), they're identical. This is where the power of Pajama lies. Pajama implements all the standard jQuery Validation methods. As a result, most rulesets used by the jQuery Validation plugin can also be used with Pajama with minimal modification to account for syntax. But wouldn't it be nice if we didn't have to do any modifications?
JSON To The Rescue
One of the biggest issues with hybrid validation is figuring out a way to share the rules between two different programming languages. Pajama solves this issue by using a common JSON rules file. Why does Pajama use a JSON rules file? Well, first off, the jQuery Validation plugin already defines its rules as JavaScript literals, so converting them to JSON is a cinche. Better yet, PHP can easily convert to and from JSON using the json_encode and json_decode functions. Thus, since both JavaScript and PHP can speak JSON, sharing rules between the languages in that format is straightforward and convenient.
To see how simple it is, here's how the rules from the above example would look as a standalone JSON file:
{
"first_name":"required",
"last_name":"required"
}
Next, to use them with client-side JavaScript, we'd modify the previous example to:
var form = $("form").on("submit", function() {
// Disable submit while loading rules.
return false;
});
$.getJSON("rules.json", function(rules) {
// Enable submit now that rules are loaded.
form.off("submit");
form.validate({
rules: rules,
submitHandler: function() {
$.post(...);
}
});
});
...and modify the PHP slightly to:
\Pajama\Validator::validate(array(
'model' => $_POST,
'rules' => json_decode('rules.json', true),
'validHandler' => function() {
// Store in database.
},
));
Presto! We now have a single rules file being used by both the client and the server to validate. If any of the rules need to change, we just need to edit that single file.
And That's Not All
In addition to the basic functionality outlined in this post, Pajama also supports custom validation methods and a small subset of CSS selectors that can be used for conditional rules. For more information on these subjects, refer to the GitHub page.
2 comments