Basics / Controllers
Controllers & FormRequests
Archery handles requests seamlessly through rich HttpRequest extensions and the highly capable FormRequest class, allowing you to access inputs, uploads, and generate intuitive HTTP responses.
Accessing the Request Context
In Archery, request handlers receive an HttpRequest object. The framework enhances this native Dart object with convenience extensions to inspect incoming data and craft outgoing responses.
Resolving Form Data
The FormRequest class acts as a single source of truth for body payload and query string data. It supports application/json, application/x-www-form-urlencoded, and multipart/form-data.
You can access the form wrapper using the request.form() extension:
router.post('/profile/update', (request) async {
final form = request.form();
// Retrieve an individual input value (checks body then query)
final email = await form.input('email');
// Retrieve all parsed form data
Map<String, dynamic> data = await form.all();
// Retrieve strictly body fields or query parameters
Map<String, dynamic> body = await form.body();
Map<String, String> query = form.query;
});
Note: The request stream is automatically buffered on the first call to any async form() method, preventing issues where the request stream is listened to multiple times.
Retrieving the Authenticated User
If you are using Archery's authentication system, you can retrieve the current User directly from the request:
final user = await request.user;
if (user != null) {
print("Welcome back, ${user.email}");
}
Generating Responses
Instead of manually crafting Dart HTTP responses, Archery’s HttpRequest extensions let you fluently return views, JSON payloads, plain text, and redirects.
Rendering Views
Return a beautifully templated HTML view using request.view(). To bind data to the view, simply provide it as a Dart Map.
router.get('/', (request) async {
return request.view('dashboard.index', {
'title': 'Project Dashboard',
'stats': [12, 34, 56],
});
});
The framework automatically injects session state and a robust CSRF token. The method will properly terminate the response context with strict security headers applied.
JSON Responses
Returning an API response is as easy as invoking request.json(). It will take a standard mapping or string, automatically encode it to JSON, and provide proper application/json content-type boundaries.
// Native encoding
return request.json({
'status': 200,
'message': 'Action successful'
});
// Working with domain models
return request.json(user.toJson());
Redirects
You can chain elegant redirects leveraging string helpers or context references.
// Redirect to absolute/relative paths
request.redirectTo(path: '/login');
// Redirect smartly back to the referring URL
request.redirectBack();
// Common destinations
request.redirectHome();
request.redirectToDashboard();
Flashing Session Messages
A common practice after a form submission is to redirect back to a given view, flashing a message or error for the user to consume during their next request cycle.
router.post('/post', (request) async {
// Store a temporary success message
request.flash(
key: 'success',
message: 'Post created successfully.'
);
// Store an error
request.flash(
key: 'title',
message: 'The title field is required.',
type: FlashMessageType.error,
);
return request.redirectBack();
});
Database Fast Failures
If you are incorporating Archery's built-in ORM, you can locate models right off the request wrapper. This provides beautiful fallback behaviors, like rendering your core 404 pages immediately when records are not found.
// Using ID
final post = await request.findOrFail<Post>(id: 42);
// Using a custom column
final user = await request.firstOrFail<User>(
field: 'email',
value: 'jane@example.com'
);