New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple sub routing system #74

Closed
bubulemaster opened this Issue May 8, 2017 · 4 comments

Comments

Projects
None yet
4 participants
@bubulemaster
Copy link

bubulemaster commented May 8, 2017

Hi all,

if you want use both createStaticHandler and createRpcHandler with shelf_io.serve(), you cannot do this natively.

I purpose to create a PR to add this method in shelf_io.dart to do this easly.

import 'package:shelf/shelf.dart';
import 'dart:core';

/// Creates a Shelf [Handler] that allow to register some Shelf [Handler] like
/// [createStaticHandler] or [createRpcHandler] on same listener.
/// Just give map [routing] to link [key] that represent path to [value] that
/// contain handler.
/// The path [key] is only static path.
Handler createSubHandler(Map<String, Handler> routing) {
  return (Request request) {
    // Selected path
    String selectedPath = '';

    routing.forEach((key, value) {
      String currentPath = '/' + request.url.path;

      if (currentPath.startsWith(key)
        && currentPath.length > selectedPath.length) {
        selectedPath = key;
      }
    });

    Handler h = routing[selectedPath];

    if (h == null) {
      return new Response.notFound('Not Found');
    } else {
      Uri requestUri = request.requestedUri;

      Uri newRequestedUri = new Uri(
        scheme: requestUri.scheme,
        userInfo: requestUri.userInfo,
        // Getter return empty string if host is null
        host: requestUri.host.length == 0 ? null : requestUri.host,
        port: requestUri.port,
        path: requestUri.path.substring(selectedPath.length - 1),
        query: requestUri.query,
        queryParameters: requestUri.queryParameters,
        fragment: requestUri.fragment);

      Uri url = request.url;

      Uri newUrl = new Uri(
        scheme: url.scheme,
        userInfo: url.userInfo,
        // Getter return empty string if host is null
        host: url.host.length == 0 ? null : url.host,
        port: url.port,
        path: url.path.substring(selectedPath.length - 1),
        query: url.query,
        queryParameters: url.queryParameters,
        fragment: url.fragment);

      Request newRequest = new Request(request.method, newRequestedUri,
        protocolVersion: request.protocolVersion,
        headers: request.headers,
        handlerPath: request.handlerPath,
        url: newUrl,
        body: request.readAsString().asStream(),
        encoding: request.encoding,
        context: request.context,
        onHijack: request.hijack);

      return h(newRequest);
    }
  };
}

Its use like:

// Create a Shelf handler for your RPC API.
var handlerApi = shelf_rpc.createRpcHandler(apiServer);
// Create a Shelf handler for static file
var handlerStatic = shelf_static.createStaticHandler('example/files', defaultDocument: 'index.html');

var handler = shelf_io.createSubHandler({
  '/': handlerStatic,
  '/api/': handlerApi,
  '/api/toto/': otherHandler
});

Do you think is good feature ?

Have you any suggestion about this ?

Regards,

@nex3

This comment has been minimized.

Copy link
Member

nex3 commented May 16, 2017

I'd really like to keep routing out of shelf core. There's a lot of room for different, valid opinions about routing, which suggests to me that we shouldn't declare a "canonical" version in shelf itself—shelf is explicitly intended as a foundation on which other packages can be built, not a batteries-included server framework.

@nex3 nex3 closed this May 16, 2017

@bubulemaster

This comment has been minimized.

Copy link
Author

bubulemaster commented May 17, 2017

Ok, thanks for your reply

@MarkOSullivan94

This comment has been minimized.

Copy link

MarkOSullivan94 commented Feb 6, 2019

Curious if anyone has a recommendation for routing which is compatible with Dart 2.x?

I noticed there was both shelf_route and shelf_rest but both haven't been updated to support Dart 2.x

@kevmoo

This comment has been minimized.

Copy link
Member

kevmoo commented Feb 7, 2019

If you're keen @MarkOSullivan94 , I'd suggest taking the best of those options and create your own. Once you've validated it for your needs, consider publishing it for others!

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