Configuration
Ack allows for some configuration settings, although most behavior is controlled directly through the schema definitions when they are created.
Global Settings (Less Common)
In general, Ack prefers configuration per schema definition rather than global settings. However, if needed, you might manage global aspects like custom format registries or shared validation logic through your own application structure (e.g., dependency injection or service patterns).
Currently, Ack does not expose a dedicated global configuration object. Configuration is primarily done at the schema level.
Schema-Level Configuration
Most "configuration" happens when you define your schemas using the fluent API provided by Ack.
Required Fields
Fields in Ack.object are required by default. Mark a field as optional with .optional().
Ack.object({
'id': Ack.integer(),
'name': Ack.string(),
'email': Ack.string().email().optional() // Email is optional (can be omitted)
}); // id and name are required by default
Additional Properties
Control how extra fields (not defined in the schema) are handled using the additionalProperties parameter in Ack.object.
// Disallow any extra properties (default behavior)
Ack.object({
'id': Ack.integer()
}, additionalProperties: false);
// or simply:
Ack.object({
'id': Ack.integer()
});
// Allow any extra properties
Ack.object({
'id': Ack.integer()
}, additionalProperties: true);
Custom Error Messages
Built-in validation rules provide default error messages. For custom error messages, use custom constraints with the .constrain() method.
See also: Custom Error Messages in Error Handling.
// Built-in constraints use default messages
Ack.string().minLength(5); // Default: "Too short, min 5 characters"
Ack.integer().min(18); // Default: "Must be at least 18"
// For custom messages, use custom constraints (see Custom Validation section below)
Custom Validation Logic
Use .constrain() to add reusable validation logic for value-level checks, or .refine() for cross-field rules.
import 'package:ack/ack.dart';
class IsPositiveConstraint extends Constraint<double> with Validator<double> {
IsPositiveConstraint()
: super(
constraintKey: 'is_positive',
description: 'Number must be positive',
);
@override
bool isValid(double value) => value > 0;
@override
String buildMessage(double value) => 'Number must be positive';
}
final priceSchema = Ack.double().constrain(IsPositiveConstraint());
// Cross-field validation (e.g., password confirmation)
final signUpSchema = Ack.object({
'password': Ack.string().minLength(8),
'confirmPassword': Ack.string().minLength(8),
}).refine(
(data) => data['password'] == data['confirmPassword'],
message: 'Passwords do not match',
);
See the Custom Validation Guide for additional patterns.
AckType Generation
ack_generator works with top-level schemas annotated with @AckType(). Write
the schema directly, then generate an extension type wrapper around its
validated representation:
import 'package:ack/ack.dart';
import 'package:ack_annotations/ack_annotations.dart';
part 'user.g.dart';
@AckType()
final userSchema = Ack.object({
'name': Ack.string().minLength(2).maxLength(50),
'email': Ack.string().email(),
'age': Ack.integer().min(18).optional().nullable(),
}, additionalProperties: true);
After running dart run build_runner build, the generated part adds a typed
wrapper such as UserType with parse() / safeParse() helpers and typed
getters for the schema fields.
See TypeSafe Schemas and the generator README for setup details and supported schema shapes.
Summary
- Ack primarily uses schema-level configuration through methods and parameters like
.minLength(),.optional(),additionalProperties: .... - Manual schema definition is the recommended approach for production applications.
- There is currently no central global configuration object provided by Ack itself.