Validation
Declarative input validation framework with chainable rules and comprehensive error reporting. Supports common validation patterns for strings, numbers, emails, and URLs.
Import
zig
const api = @import("api");
const Validator = api.Validator;
const validation = api.validation;Validation Functions Summary
| Function | Description |
|---|---|
isEmail(str) | Validate email format |
isUrl(str) | Validate URL format |
isNotEmpty(str) | Check non-empty string |
isLengthBetween(str, min, max) | Validate string length |
isNumeric(str) | Check numeric string |
isAlpha(str) | Check alphabetic string |
isAlphanumeric(str) | Check alphanumeric string |
matchesPattern(str, pattern) | Match regex pattern |
Validator Builder Rules
| Method | Description |
|---|---|
.required(field) | Field must be present |
.minLength(field, len) | Minimum string length |
.maxLength(field, len) | Maximum string length |
.email(field) | Must be valid email |
.url(field) | Must be valid URL |
.minValue(field, val) | Minimum numeric value |
.maxValue(field, val) | Maximum numeric value |
.pattern(field, regex) | Must match pattern |
Validator Functions
isEmail
zig
pub fn isEmail(email_str: []const u8) boolValidates email format.
zig
validation.isEmail("user@example.com") // true
validation.isEmail("invalid") // falseisUrl
zig
pub fn isUrl(url_str: []const u8) boolValidates URL format.
zig
validation.isUrl("https://example.com") // true
validation.isUrl("ftp://example.com") // false (http/https only)isNotEmpty
zig
pub fn isNotEmpty(str: []const u8) boolChecks if string is not empty/whitespace.
zig
validation.isNotEmpty("hello") // true
validation.isNotEmpty("") // false
validation.isNotEmpty(" ") // falseisLengthBetween
zig
pub fn isLengthBetween(str: []const u8, min: usize, max: usize) boolValidates string length.
zig
validation.isLengthBetween("hello", 1, 10) // true
validation.isLengthBetween("hi", 5, 10) // falseValidator Builder
Creating a Validator
zig
const UserValidator = Validator(User);
var validator = UserValidator.init(allocator);
defer validator.deinit();Chaining Rules
zig
_ = validator
.required("name")
.minLength("name", 2)
.maxLength("name", 100)
.email("email")
.minValue("age", 18)
.maxValue("age", 120);Validating
zig
const result = validator.validate(user_input);
if (!result.valid) {
for (result.errors) |err| {
std.debug.print("{s}: {s}\n", .{err.field, err.message});
}
}ValidationError
zig
pub const ValidationError = struct {
field: []const u8,
message: []const u8,
code: ErrorCode,
};
pub const ErrorCode = enum {
required,
min_length,
max_length,
min_value,
max_value,
pattern,
email,
url,
custom,
};isUuid
zig
pub fn isUuid(uuid_str: []const u8) boolValidates UUID v4 format.
zig
validation.isUuid("123e4567-e89b-12d3-a456-426614174000") // true
validation.isUuid("invalid-uuid") // falseuuid Rule
Add UUID validation to the Validator builder.
zig
_ = validator.uuid("user_id");Handler Example
zig
fn createUser(ctx: *api.Context) api.Response {
const body = ctx.body();
if (body.len == 0) {
return api.Response.err(.bad_request, "{\"error\":\"Body required\"}");
}
// Parse body
const User = struct { email: []const u8 };
const user = api.json.parse(User, ctx.allocator, body) catch {
return api.Response.err(.bad_request, "{\"error\":\"Invalid JSON\"}");
};
// Validate
if (!api.validation.isEmail(user.email)) {
return api.Response.err(.bad_request, "{\"error\":\"Invalid email\"}");
}
return api.Response.jsonRaw("{\"created\":true}")
.setStatus(.created);
}