Context properties
Context properties provide type-safe, request-scoped data storage in Relic applications. They replace Shelf's Map<String, Object> context with a more robust system that attaches custom data directly to Request objects.
Common use cases:
- Store request IDs for logging and tracing.
- Cache computed values within a request (like parsed authentication tokens).
- Pass data between middleware and handlers.
- Track request-specific state (like the authenticated user or request timing).
Creating context properties
Context properties are created as global constants and attached directly to Request objects:
// Define properties (typically as global constants)
final requestIdProperty = ContextProperty<String>('requestId');
final userProperty = ContextProperty<User>('user');
final timingProperty = ContextProperty<Stopwatch>('timing');
Use descriptive names for your properties. The string identifier is used internally for storage and debugging.
Property API
Context properties provide the following methods:
| Method | Description | Returns |
|---|---|---|
property[req] = value | Set value for request | T (non-null) |
property[req] | Read value from request | T? (nullable) |
property.get(req) | Read value or throw if missing | T (non-null) |
Adding properties
Set values in middleware or handlers using the [] operator:
extension on Request {
String get requestId => _requestIdProperty.get(this);
}
final _requestIdProperty = ContextProperty<String>('requestId');
// Middleware that generates and stores a unique ID for each request.
Handler requestIdMiddleware(final Handler next) {
return (final req) async {
// Generate a timestamp-based unique ID for this request.
_requestIdProperty[req] = 'req_${DateTime.now().millisecondsSinceEpoch}';
// Pass control to the next handler in the chain.
return await next(req);
};
}
Reading properties
Read values with property[req] (returns null if missing) or property.get(req) (throws if missing):
// Handler that retrieves and displays the request ID.
Future<Response> handler(final Request req) async {
// Access the request ID (set by the middleware) using the extension method.
final requestId = req.requestId;
log('Request ID: $requestId');
return Response.ok(body: Body.fromString('Your request ID is: $requestId'));
}
Context properties exist only for the duration of the request. Once the response is sent, they're automatically cleaned up. Values are scoped to each request and do not leak between requests.
Examples & further reading
Examples
- Context Property Example - Shows how to use context properties for request IDs and user authentication.
API documentation
- ContextProperty class - Type-safe request-scoped data storage.
- Request class - HTTP request object that holds context properties.