LogoRevali

Middleware

Add request/response processing with Middleware

This tutorial walks through building two middleware components with the LifecycleComponent API: one that logs every request, and one that guards an endpoint behind an API key.

Log every request#

A LifecycleComponent method that returns MiddlewareResult acts as middleware. Bind Request to inspect the incoming request:

lib/components/request_logger.dart
import 'package:revali_router/revali_router.dart';

class RequestLogger implements LifecycleComponent {
  const RequestLogger();

  MiddlewareResult logRequest(Request request) {
    print('[${request.method}] ${request.uri.path}');

    return const MiddlewareResult.next();
  }
}

Apply it to an endpoint, controller, or the whole app by using it as an annotation:

routes/controllers/some_controller.dart
import 'package:revali_router/revali_router.dart';

@Controller('some')
class SomeController {
  const SomeController();

  @RequestLogger()
  @Get('logged')
  String logged() => 'logged';
}

Every request to GET /some/logged prints a line like [GET] /some/logged to the server's console before the endpoint runs.

Guard an endpoint with an API key#

Middleware can also stop a request before it reaches the endpoint, and share data with it via Data:

lib/components/require_api_key.dart
import 'package:revali_router/revali_router.dart';

class RequireApiKey implements LifecycleComponent {
  const RequireApiKey();

  MiddlewareResult checkApiKey(
    @Header('X-Api-Key') String? apiKey,
    Data data,
  ) {
    if (apiKey == null) {
      return const MiddlewareResult.stop(
        statusCode: 401,
        body: 'Missing X-Api-Key header',
      );
    }

    data.add(apiKey);
    return const MiddlewareResult.next();
  }
}

The endpoint reads the value middleware stored in Data using the @Data() annotation:

routes/controllers/some_controller.dart
@RequireApiKey()
@Get('protected-by-middleware')
String protectedByMiddleware(@Data() String apiKey) => 'key: $apiKey';
  • A request without X-Api-Key gets 401 Missing X-Api-Key header and never reaches protectedByMiddleware.
  • A request with X-Api-Key: my-key-123 reaches the endpoint, which echoes back key: my-key-123.

What's next?#