Appearance
Validation
The framework includes a validation engine inspired by Laravel. It provides reusable rule classes for checking request data.
Available Rules
Each rule is a class in framework::support::validation::rules.
| Rule | Description | Example |
|---|---|---|
required | Field must be present and non-empty | rules::required() |
string | Value must be a string | rules::string() |
integer | Value must be an integer | rules::integer() |
numeric | Value must be numeric (int or float) | rules::numeric() |
boolean | Value must be true/false | rules::boolean() |
array | Value must be a JSON array | rules::array() |
object | Value must be a JSON object | rules::object() |
email | Value must be a valid email | rules::email() |
ip | Value must be a valid IP address | rules::ip() |
url | Value must be a valid URL | rules::url() |
uuid | Value must be a valid UUID | rules::uuid() |
regex(pattern) | Value must match the regex | rules::regex("^[a-z]+$") |
min(n) | Minimum length or numeric value | rules::min(3) |
max(n) | Maximum length or numeric value | rules::max(255) |
size(n) | Exact length or numeric value | rules::size(10) |
in(values...) | Must be one of the listed values | rules::in({"a", "b"}) |
not_in(values...) | Must not be one of the listed values | rules::not_in({"x", "y"}) |
alpha | Must contain only letters | rules::alpha() |
alpha_num | Must contain only letters and numbers | rules::alpha_num() |
alpha_dash | Letters, numbers, dashes, underscores | rules::alpha_dash() |
confirmed | Field must have matching _confirmation field | rules::confirmed() |
same(field) | Must match another field | rules::same("password") |
different(field) | Must differ from another field | rules::different("old_password") |
nullable | Field can be null (bypasses other rules) | rules::nullable() |
present | Field must be present in the data | rules::present() |
Rule Base Class
Every rule extends framework::support::validation::rule and implements two methods:
cpp
#include <framework/support/validation/rules.hpp>
// bool validate(const std::string& attribute, const boost::json::value& value, const boost::json::object& data)
// Returns true if the value passes the rule.
// `attribute` is the field name, `data` is the full object (for cross-field rules).
//
// std::string message(const std::string& attribute) const
// Returns the error message for when validation fails.The is_implicit() method can be overridden (returns false by default). Implicit rules like required and nullable are checked even when the field is absent.
Using Rules Directly
Instantiate rules and call validate() on individual values.
cpp
#include <framework/support/validation/rules.hpp>
using namespace framework::support::validation;
rules::required required_rule;
rules::email email_rule;
rules::min min_len(3);
rules::max max_len(255);
auto& obj = body.as_object();
bool valid = required_rule.validate("name", obj.at("name"), obj);
bool is_email = email_rule.validate("email", obj.at("email"), obj);Building a Validator for HTTP Routes
For HTTP routes, the validator is a function that receives the full http_request and returns a pair: {is_valid, errors_map}.
cpp
using namespace framework;
using namespace framework::clients::http;
auto user_validator = [](const http_request& req)
-> std::pair<bool, std::unordered_map<std::string, std::vector<std::string>>> {
if (!req.body_.has_value()) {
return {false, {{"body", {"Request body is required"}}}};
}
auto& obj = req.body_->as_object();
std::unordered_map<std::string, std::vector<std::string>> errors;
// Use rule classes to validate
rules::required required;
rules::email email;
if (required.is_implicit() || obj.contains("name")) {
if (!required.validate("name", obj.contains("name") ? obj.at("name") : nullptr, obj)) {
errors["name"].push_back(required.message("name"));
}
}
if (obj.contains("email") && !email.validate("email", obj.at("email"), obj)) {
errors["email"].push_back(email.message("email"));
}
if (!errors.empty()) {
return {false, errors};
}
return {true, {}};
};
// Attach the validator to a route
app.register_endpoint(
http_verb_t::post,
"/users",
create_user_handler,
user_validator
);Error Responses
When validation fails, the framework returns a 422 Unprocessable Entity response. The body contains the field-level error map.
json
{
"name": ["The name field is required."],
"email": ["The email field is required."]
}Each field maps to an array of error messages, allowing multiple validation failures per field.