Middleware runs before guards
and the endpoint. Use it to prepare the request, for example by loading the current user into Data
or setting a response header. It can also stop the request early. If the only job is to allow or deny access, write a
guard instead.
Example#
import 'package:revali_router/revali_router.dart';
class Tenant implements LifecycleComponent {
const Tenant();
MiddlewareResult resolve(@Header('X-Tenant') String? tenant, Data data) {
if (tenant == null) {
return const MiddlewareResult.stop(body: 'X-Tenant header is required');
}
data.add(TenantId(tenant));
return const MiddlewareResult.next();
}
}
class TenantId {
const TenantId(this.value);
final String value;
}
import 'package:revali_router/revali_router.dart';
@Tenant()
@Controller('orders')
class OrdersController {
const OrdersController();
@Get()
String list(@Data() TenantId tenant) => 'orders for ${tenant.value}';
}
curl -H 'X-Tenant: acme' http://localhost:8080/api/orders
# 200 {"data":"orders for acme"}
curl http://localhost:8080/api/orders
# 400 X-Tenant header is required
In debug mode the 400 body also has a __DEBUG__ block appended.
Results#
| Result | Effect |
|---|---|
MiddlewareResult.next() |
Continue to the next middleware, then to the guards. |
MiddlewareResult.stop({statusCode, headers, body}) |
End the request. The status defaults to 400. |
The method can be async and return Future<MiddlewareResult>. stop
takes the same arguments as the other error results. See Error Responses.
Classic Style#
As an alternative, implement Middleware and its use method, which receives the whole
Context:
import 'package:revali_router/revali_router.dart';
class TenantMiddleware implements Middleware {
const TenantMiddleware();
@override
Future<MiddlewareResult> use(Context context) async {
final tenant = context.request.headers.get('X-Tenant');
if (tenant == null) {
return const MiddlewareResult.stop();
}
context.data.add(TenantId(tenant));
return const MiddlewareResult.next();
}
}
Apply it with @TenantMiddleware(), or by type with @Middlewares([TenantMiddleware]).