Skip to content
Download

Understanding Validation

Mach can validate request models automatically when they are bound from the request body.

A model defines its validation rules through a validate() method, and Mach applies those rules before the endpoint handler runs.

Consider a registration request:

struct RegisterRequest {
std::string username;
std::string email;
int age;
void validate(mach::ValidationBuilder<RegisterRequest>& validation) const {
validation.field(&RegisterRequest::username)
.minLength(3)
.maxLength(30);
validation.field(&RegisterRequest::email).email();
validation.field(&RegisterRequest::age).min(18);
}
};
MACH_DEFINE_JSON(RegisterRequest, username, email, age)

The validate() method receives a mach::ValidationBuilder<T> for the current model.

Use field() to select a member and define the rules that apply to it.

For example:

validation.field(&RegisterRequest::username)
.minLength(3)
.maxLength(30);

This requires username to contain between 3 and 30 characters.

Validation works together with request-body model binding.

For example:

app.mapPost("/register", [](RegisterRequest request) {
return mach::ok("Registration accepted");
});

When Mach binds the request body to RegisterRequest, it also applies the validation rules defined by the model.

The endpoint therefore receives a request model only after the body has been successfully bound and validated.

Validation rules are defined next to the data they describe:

struct RegisterRequest {
std::string username;
std::string email;
int age;
void validate(mach::ValidationBuilder<RegisterRequest>& validation) const {
validation.field(&RegisterRequest::username)
.minLength(3)
.maxLength(30);
validation.field(&RegisterRequest::email).email();
validation.field(&RegisterRequest::age).min(18);
}
};

This keeps the requirements for a request model in one place instead of duplicating checks inside endpoint handlers.

The handler can focus on what should happen once the request is valid.

You do not call validate() manually from the endpoint.

Once the model provides the expected validation method, Mach handles validation as part of request processing.

A complete example looks like this:

struct RegisterRequest {
std::string username;
std::string email;
int age;
void validate(mach::ValidationBuilder<RegisterRequest>& validation) const {
validation.field(&RegisterRequest::username)
.minLength(3)
.maxLength(30);
validation.field(&RegisterRequest::email).email();
validation.field(&RegisterRequest::age).min(18);
}
};
MACH_DEFINE_JSON(RegisterRequest, username, email, age)
int main() {
mach::AppBuilder builder;
auto app = builder.build();
app.mapPost("/register", [](RegisterRequest request) {
return mach::ok("Registration accepted");
});
return app.run();
}

Next, you’ll learn how to define validation rules for individual fields.