Skip to content

Shelf dynamic routes without the need to use mounts #485

Open

Description

@guibbv2011

davidmartos96
jonasfj

If this separation of routes and dynamic routes is possible to do with vanilla shelf and router (no codegen) I would love to see it in action.

I build a package to "solve" this issue (https://pub.dev/packages/shelf_dynamic_forwarder)
https://github.com/guibbv2011/shelf_dynamic_forwarder

I don't use the mount function instead I call directly:

  return await handler!(subReq);

This will link the child router defined in map dynamicRoutes.

Here a example usage:

import 'dart:io';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'package:shelf_dynamic_forwarder/shelf_dynamic_forwarder.dart';
import 'package:shelf_router/shelf_router.dart';

Router get filenamesRequest {
  final handler = Router();
  handler.get('/filenames', (Request req) async {
    // Your logic code here..
    return Response.ok('');
  });
  return handler;
}

Router get fileRequest {
  final handler = Router();
  handler.get('/file', (Request req) async {
    // Your logic code here..
    return Response.ok('');
  });
  return handler;
}

final Map<String, Handler> dynamicRoutes = {
  'filenames': filenamesRequest,
  '.*': fileRequest,
};

Handler get router {
  final dynamicRouter = createDynamicRouter(
    routePattern: '/api/<adminId>/<index>/<path|.*>',
    routes: dynamicRoutes,
  );
  return dynamicRouter;
}

void main() async {
  final handler = 
    const Pipeline().addMiddleware(logRequests()).addHandler(router);
  await serve(handler, 'localhost', 8080);
}

And how I implemented it:

    // Create a new ABSOLUTE URI for the child router.
    // This isolates the child from the parent's base path and ensures the URI is absolute.
    final originalUri = request.requestedUri;

    final newUri = originalUri.replace(
      // Explicitly retain scheme, host, and port for absolute URI
      // Reset the path to only what the child router expects (e.g., /filenames)
      // pathSegments must be an Iterable<String>
      pathSegments: [pathSegment],
    );

    // 4. Create a brand new Request object using the new absolute URI.
    final subReq = Request(
      request.method,
      newUri,
      headers: newHeaders,
      body: await request.read(),
      context: request.context,
    );
}

Originally posted by @guibbv2011 in #288 (comment)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions