Skip to content

Proposal: support middleware in shelf_router_generator #388

@aci8

Description

@aci8

Motivation

I would propose to add middleware support in the shelf_router_generator. Currently, to use the router_generator with middleware, you can write something like this:

@Route.get('/user/<userId>')
Future<Response> getUser(Request request, String userId) async {
    return Pipeline()
        .addMiddleware(logging)
        .addMiddleware(authorization)
        .addHandler((request) async {
            // do something with request and(!) userId variables
        })(request);
  }

This creates a lot of repetitive and boilerplate code for a routine (and quite frequent) action (the use of middleware). This code could be generated automatically.

Possible solution design

I see 2 possible paths:

  1. Add a Middleware Annotation (similar to the one described here Add middleware for handlers #338)
    In this case, the above code would look something like this:

    @Middleware(logging)
    @Middleware(authorization)
    @Route.get('/user/<userId>')
    Future<Response> getUser(Request request, String userId) async {
      // do something with request and userId variables
    }
  1. Add an annotation to the Route constructor parameter List<Middleware> middlewares
    In this case, code would look something like this:

    @Route.get('/user/<userId>' middlewares: [logging, authorization])
    Future<Response> getUser(Request request, String userId) async {
      // do something with request and userId variables
    }

The generated code could look something like this in both cases (such a construct is necessary to preserve the passing of the PATH parameters to the client handler):

Router _$UserServiceRouter(UserService service) {
  final router = Router();
  router.add(
    'GET',
    r'/user/<userId>',
    (Request request, String userId) => 
      Pipeline()
        .addMiddleware(logging)
        .addMiddleware(authorization)
        .addHandler((request) => service.getUser(request, userId))(request),
    // or just: (logging(authorization((request) => service.getUser(request, userId))))(request)
  );
  return router;
}

I believe the second solution (with the middlewares parameter) is more successful and I could attempt to make the necessary changes and create a pull request myself.

Is this a good idea?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions