dart_frog icon indicating copy to clipboard operation
dart_frog copied to clipboard

feat: Allow routing parameters in `middleware`

Open rubenferreira97 opened this issue 2 years ago • 4 comments

Description Currently is not possible to access routing parameters on middlewares. Would be nice in cases where we have nested routing parameters and have different logic dependent on that parameter (e.g. /[userId]/tasks/[taskId], middleware on /[userId]/_middleware.dart that checks if we have permissions for that [userId) .

My current workaround relies on private implementations 😕:

Middleware /[test]/_middleware.dart:

import 'package:dart_frog/dart_frog.dart';
import 'package:dart_frog/src/_internal.dart' show toShelfHandler;

Handler middleware(Handler handler /* String test */) { // `String test` does not work
  return fromShelfHandler((request) async {
    print((request.context['shelf_router/params'] as Map<String, String>?)?['test']);
    return toShelfHandler(handler)(request);
  });
}

Index /[test]/index.dart:

Future<Response> onRequest(RequestContext context, String test) async {
  return Response(body: '$test');
}

rubenferreira97 avatar Jul 18 '23 17:07 rubenferreira97

Hi @rubenferreira97 👋 This is already possible:

Handler middleware(Handler handler) {
  return (context) {
    final request = context.request;
    // Do something with the request
    return handler(context);
  };
}

felangel avatar Jul 18 '23 22:07 felangel

@felangel Thanks for you answer!

Sorry if I am missing something but first I guess you meant context.request instead of request.context, second neither request or context expose routing params as far as I know.

Middleware /[test]/_middleware.dart:

Handler middleware(Handler handler) {
  return (context) {
    final request = context.request;
    print(request['test']); // does not work
    print(context['test']); // does not work
    // Do something with the request
    return handler(context);
  };
}

In a ideal scenario I would like to access the variable in a typesafe manner via the middleware params, however I don't know if this is possible. I imagine middlewares are different from requests.

Handler middleware(Handler handler, String test) {
  return (context /*, test */) { // or here?
    print(test);
    return handler(context);
  };
}

rubenferreira97 avatar Jul 18 '23 23:07 rubenferreira97

You can do the following:

Handler middleware(Handler handler) {
  return (context) {
        final uri = context.request.uri;

        if (uri.pathSegments.contains('test')) {
          return Response(body: 'OK');
        }
        return handler(context);
      };
}

niklasbartsch avatar Jul 25 '23 15:07 niklasbartsch

@niklasbartsch In that example I can't access the variable value.

rubenferreira97 avatar Jul 25 '23 17:07 rubenferreira97