Skip to main content

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');
Property naming

Use descriptive names for your properties. The string identifier is used internally for storage and debugging.

Property API

Context properties provide the following methods:

MethodDescriptionReturns
property[req] = valueSet value for requestT (non-null)
property[req]Read value from requestT? (nullable)
property.get(req)Read value or throw if missingT (non-null)

Adding properties

Set values in middleware or handlers using the [] operator:

Add request ID to context
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):

Use request ID from context
// 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'));
}
Property lifetime

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

API documentation