p-hatan/ mirror

pub repository

mirror.p-hatan.ir

shelf_route

0.7.1

Routing middleware for Shelf

Download archive

Readme

Router for Dart Shelf

Build Status

Introduction

Provides Shelf middleware for defining routes.

Shelf Route is a powerful router that makes it easy to define routes in a modular way.

Shelf Route:

  • focuses solely on routing, leaving other concerns like binding, validating, error handling etc to other middleware components
  • uses Shelf Path for storing path parameters in the Shelf Request context for interoperability with compatible middleware like Shelf Bind
  • supports defining routes heirarchically for greater modularity
  • supports custom path formats
  • supports custom handler adapters

This makes it very versatile and lets you mix and match it with your other favourite Shelf middleware components.

Using

Basics

You create a router using the router function

var myRouter = router();

Use the router's get method to add a route using the GET Http method

myRouter.get('/', (_) => new Response.ok("Hello World");

Use the router's handler property to obtain a Shelf Handler

var handler = myRouter.handler;

Now you can serve up your routes with Shelf IO

io.serve(handler, 'localhost', 8080);

Http Methods

It supports all the standard http methods

myRouter..get('/', (_) => new Response.ok("Hello World"))
        ..post('/', (_) => new Response.ok("Hello World"))
        ..put('/', (_) => new Response.ok("Hello World"))
        ..delete('/', (_) => new Response.ok("Hello World"));

You can specify several methods by using add

myRouter.add('/', ['GET', 'PUT'], (_) => new Response.ok("Hello World"));

Path Parameters

Shelf Route uses UriPattern to define the paths to match on for each route. This means you can use whatever format for the paths that you like as long as it implements this interface.

By default it uses UriTemplate which implements the powerful standard of the same name.

UriTemplate allows binding to both:

  • path segments like /greeting/fred
  • query parameters like /greeting?name=fred

It uses {parameter name} notation to denote path parameters.

myRouter.get('/{name}', (request) =>
          new Response.ok("Hello ${getPathParameter(request, 'name')}"));

Path parameters are fetched via Shelf Path's getPathParameter function.

Similarly you can also bind to query parameters

myRouter.get('/{name}{?age}', myHandler);

myHandler(request) {
  var name = getPathParameter(request, 'name');
  var age = getPathParameter(request, 'age');
  return new Response.ok("Hello $name of age $age");
}

Hierarchical Routers

To improve modularity you can break up your routes into a series of nested routes.

For example you can add a child router for all routes starting with /banking

var rootRouter = router();

var bankingRouter = rootRouter.child('/banking');

Now you can add routes to the banking router as normal

bankingRouter
    ..get('/account/{accountNumber}', fetchAccountHandler)
    ..post('/account/{accountNumber}/deposit', makeDepositHandler);

Then serve up all the routes via the rootRouter

io.serve(rootRouter.handler, 'localhost', 8080)

Note in this case the full path of the deposit resource is actually

/banking/account/{accountNumber}/deposit

To try this out, fire up the server and do

curl -d 'lots of money' http://localhost:8080/banking/account/1235/deposit

Route Specific Middleware

You can add additional middleware to individual routes

myRouter.get('/', (_) => new Response.ok("Hello World"), middleware: logRequests());

This middleware will be applied to all requests on that route.

If you add it to a child router it will apply to all routes for that router

var bankingRouter = rootRouter.child('/banking', middleware: logRequests());

will apply to all banking routes.

Custom Path Formats

The path arguments of all the router methods accept either:

  • a String or
  • a UriPattern

By default String value will be parsed into a UriParser which means it is expected to conform to UriTemplate.

You can also implement your own UriPattern and use that instead. For example you may prefer the : style of path variables (e.g. :name).

In addition it allows you to create uri path definitions and potentially share between client and server. e.g.

var accountPattern = new UriParser(new UriTemplate('/account/{accountNumber}'));

You can now use this when you define a route and on the client.

myRouter.get(accountPattern, (_) => new Reponse.ok("Hello World"));

Installing a Custom Path Adapter

To make it more seamless to use your own path style you can install a path adapter into the router. This will be used by all routes in this router and any child routers unless you override it somewhere.

Install the adapter by passing it to the router function.

var colonStyleAdapter = ....; // obtain the adapter from somewhere

var myRouter = router(pathAdapter: colonStyleAdapter);

Now you can use colon style path parameters

myRouter.get('/:name', (request) =>
          new Response.ok("Hello ${getPathParameter(request, 'name')}"));

Custom Handler Adapters

You can install a custom handler adapter, which allows you to transform the handlers passed into the Router's methods. This allows for more seamless integration with other Shelf packages.

For example if you want to use ordinary Dart functions as handlers you can use a package like Shelf Bind. Shelf Bind provides such an adapter out of the box.

Install the adapter by passing it to the router function.

var myRouter = router(handlerAdapter: bind.handlerAdapter)

Now you can do

myRouter.get('/{name}', (name) => "Hello ${name}");

instead of

myRouter..get('/{name}', (request) =>
          new Response.ok("Hello ${getPathParameter(request, 'name')}"));

Note without installing the adapter you could still call Shelf Bind's bind method directly.

myRouter.get('/{name}', bind((name) => "Hello ${name}"));

Custom Route Creators

If you have some method of creating routes then it's easy to glue in.

First implement the Routeable interface

class MyRouteCreator implements Routeable {
  void createRoutes(Router router) {
    router..get('/', (_) => new Response.ok("Hello World"))
          ..get('/greeting/{name}', (request) =>
              new Response.ok("Hello ${getPathParameter(request, 'name')}"));
  }
}

Then add it to another router

rootRouter.addAll(new MyRouteCreator());

Printing Routes

It's easy to see all the routes defined for a router using the printRoutes function.

var router = r.router()
  ..get('/', (_) => new Response.ok("Hello World"))
  ..post('/', (_) => new Response.ok("Hello World"))
  ..get('/greeting/{name}{?age}', (request) {
    var name = getPathParameter(request, 'name');
    var age = getPathParameter(request, 'age');
    return new Response.ok("Hello $name of age $age");
  });
  
printRoutes(router);

prints

GET     ->      /
POST  ->      /
GET     ->      /greeting/{name}{?age}

Examples

See more detailed examples in the example folder under the project source.

More Information

See the wiki for more details on all the options

Contributing

Contributions are welcome. Please:

  1. fork the repo and implement your changes with good unit test coverage of your changes
  2. create a pull request and include enough detail in the description

TODO

See open issues.

Authors

Changelog

0.7.1

  • Added fallbackHandler to router function
  • call handlerAdapter on fallbackHandler
  • added ALL_METHODS constant

0.7.0+1

  • Fixed use of Deprecated

0.7.0

  • Fixed spelling of Adapter in several classes (thanks Michael Goodness for the contribution)

0.6.0

Major release with lots of changes including:

  • custom path adapters
    • Allows you to plugin any path style you like (e.g. /:foo)
  • custom handler adapters
    • Seamless integration with other Shelf components like Shelf Bind so you can use ordinary Dart functions as Shelf Handlers. For example:
  var myRouter = router(handlerAdapter: bind.handlerAdapter)
  myRouter.get('/{name}', (name) => "Hello ${name}");
  • Support for Shelf Path to remove direct dependency of handlers to Shelf Route
  • Easy to add per route middleware
  • print all routes in a router
  • control over exact path matching
  • Fixed path handling on windows

0.5.0

  • Upgraded to shelf 0.5.1. Note this is only a breaking change for those that directly accessed the path variables in the header. Unfortunately the example and doco did this so I made this a major release

0.4.0

  • Upgraded to shelf 0.5.0

0.3.1

0.3.0

0.2.0+1

  • Fixed handling of routes that are just a path variable

0.2.0

  • Upgraded to shelf 0.4.0

0.1.2+1

  • Fixed bug where body was missing on copied request

0.1.2

  • Added helper function getPathVariables to encapsulate extracting path variables stored in the request

0.1.1

  • Added support for path variables.

  • Improved tests.

Installing

export PUB_HOSTED_URL=https://pub.mirror.p-hatan.ir
flutter pub add shelf_route
pubspec.yaml
name: shelf_route
version: 0.7.1
author: Anders Holmgren <andersmholmgren@gmail.com>
description: Routing middleware for Shelf
homepage: https://bitbucket.org/andersmholmgren/shelf_route
environment:
  sdk: '>=1.4.0 <2.0.0'
dependencies:
  matcher: '>=0.10.0 <0.12.0'
  mock: '>=0.11.0+1 <0.12.0'
  path: '>=1.1.0 <2.0.0'
  shelf: '>=0.5.4+2 <0.6.0'
  shelf_path: '>=0.1.0 <0.2.0'
  uri: '>=0.9.2 <0.10.0'
dev_dependencies:
  shelf_exception_response: '>=0.1.0 <0.2.0'
  unittest: '>=0.10.1 <0.12.0'

Version history

VersionPublishedArchiveSHA-256
0.1.02014-04-05T01:42:32.871200ZDownload25b49b0ef930d513e3ae576d718d992c852d80b9b412d180d8e9bbf59b5d287f
0.1.0+12014-04-05T01:45:53.983660ZDownloade31120b07b38136a984b7acb224572f0c13b3e81f70ae142dc3111155cd4f0bd
0.1.0+22014-04-05T07:11:36.732650ZDownloadfe74e11d82321c6d138877c494d7ffbb62261a2ef7e28db3e399983b775c4907
0.1.1+12014-04-06T05:36:58.393550ZDownload23481e07612d85f39a4fa7e0e39bfd3681552c080d69f9c0bd724d2dfb9f1f2c
0.1.22014-04-07T01:55:19.090490ZDownload772251271f22b23c1203a3d58f61bc9138030fe8a5ba0542dc3b73b8c6c5d1f3
0.1.2+12014-04-07T02:54:32.068370ZDownload0ee0ac1a807e3f490de280492ce7fff6075550866914adc1e81fedd46210a867
0.2.02014-04-11T05:21:21.528060ZDownload70609f8398e271ab3ad145b6d514fee3d0f1896f009e6bace7ba0998777ec688
0.2.0+12014-04-12T00:53:31.449850ZDownload1c152007cc727a37ed49eb51d433b110c5e12bd46c18409c176eba3a7d9f7654
0.3.02014-04-12T03:38:15.180330ZDownload1a80fd1f86b7a79dc239877daa0c2e5028818fa6fa2ac173a1dc60c1c353e506
0.3.12014-04-12T05:22:34.890670ZDownloadef54b51195251c63a54d11372a396d03334aabace49315e37e52b942aaeb4204
0.4.02014-04-17T22:07:44.016450ZDownloadf2e5458b8f96a11770a9354d0ddfc9e3d58ac3f7eb485fdb17ee0197307c1533
0.5.02014-04-20T01:27:29.741040ZDownload3493204b1501efdad70b301df95f0ec032380e4e35b053fc9e00e4341a83abc3
0.6.02014-07-13T07:21:40.436370ZDownloada44a8a992e9a0fa9a5ebd4fcdd45466719e0a93abd9599b7baf0c31bf022238f
0.7.02014-07-22T20:51:52.644530ZDownloadf6bad62a92f15d74e839f2379fafe5a8b200ff1e3559d0e15a37168b2a8607c7
0.7.0+12014-08-06T09:55:26.066900ZDownload3fb49faf50659dd6f7824f6fdc082963fb821350469da7730fce1de2d0acc363
0.7.12014-08-09T07:40:50.426980ZDownloade233b1103355bc35d16bae8da188d57a1cbe0d13ea2b81fb1554293a802f80dc
0.8.02014-09-30T20:17:50.098080ZDownload74333ef252c861fe64872fdb4c8db0240784d592a5a35bbd68116d0126f8a7a5
0.8.0+12014-10-08T07:06:03.210550ZDownload6fe60973c8988e10c2208538f83bc4bd655685d05475cc3cb2739ca7023c1e1b
0.9.02014-10-11T01:23:32.159570ZDownload16e19c6634258cd0013a43b7b395048f4b28464c41a613e532daa2efd5587ca8
0.10.02014-10-17T05:51:45.692520ZDownload2893c304ff16aaa25a56fc98f152f051f175ce9e3d3440a479b6cc372c3f9fdd
0.10.12014-10-17T23:59:42.257370ZDownload3127353c2819f0c568411bff33fdf61fce023071bd58771217816e480e5971ea
0.11.02014-11-01T01:43:28.127ZDownload933c6355649cdd6995100b9859637d6ff20f1680d1e38f5b9a7484903c0e31c1
0.11.0+12014-11-08T23:13:46.970400ZDownload42373cb88fe67876cc2a68fcc3462d4f28d3ac87a50d0ac79a9524ef1d5341c7
0.12.02015-03-20T23:25:56.164460ZDownload0ad04e64806ec2e6b0ee545ccb945ce1bf6ab10c660b06d446b106521097f044
0.13.0-beta.12015-06-20T21:29:49.961ZDownloade818d7205e1066d1c485852faf007807039836d19f6a119e127dc36b2cde12a9
0.13.0-beta.22015-06-21T18:59:01.659ZDownload55a9c835cf2de813c07463ce4b9a25957452f2dcdfa6908bd5b92c2772ee3545
0.13.0-beta.32015-06-23T20:50:28.882ZDownloadf3271a77d3a045444276dc1c30691b666525d41cc23664a26cce521fac1bcd0f
0.13.0-beta.42015-06-25T10:37:40.689ZDownloadf3c08f381ee829cc685f772f82418570c9128d593260feeaf82a05d746410e5e
0.13.02015-06-25T11:08:03.385ZDownload1de8644648417292dfe0f9569a52dc33c3a9ad726e5b96ce5742babed2caf2b3
0.13.12015-06-25T12:22:52.783ZDownloade4cd7d8046fa13bfdc691a94882c512e807717f3cb5ff360692ace54ed62f3ee
0.13.22015-06-26T06:58:26.421ZDownloadf38e980a87f3b4395c2b7d3f566254c174afb2bb1cb356b926521d535081927d
0.13.32015-07-01T21:24:04.810ZDownloadd2cc5d7e4cb543941ece4e89754f6282c46742cd61cf105656953e71eedc4e88
0.13.42015-07-04T05:13:28.163ZDownloaddc74b577bb8f76fe223266b8358be88dc4f04d875d6200913ade3c0162b5bc4d
0.13.52015-08-12T23:10:04.490ZDownload0e1cdb8883f3aac8e500795d08e626288b44b7615076ef570691f0f162dd401a
0.14.02015-08-30T22:11:53.122ZDownload03a3c4faa535ca26da1b629ed0ede7636a977e37cee4e0e0b49d826deff6b153
0.14.12016-01-06T06:48:13.797ZDownload1639423b95704088bae9187584b67865d4e1068424957c9f9aa4b978208e669b
0.14.22016-04-10T01:56:50.717ZDownload19a05d0c7a350cbc9c9b0c8870c836737bcbffe1270830406f9d0878e39af654
0.14.32016-10-03T00:44:06.878ZDownload5507724c06f120d8aa50e3925e2871e68f95129b86741d29050ebc388f071891

Dependencies

matcher "\u003e=0.10.0 \u003c0.12.0"

mock "\u003e=0.11.0+1 \u003c0.12.0"

path "\u003e=1.1.0 \u003c2.0.0"

shelf "\u003e=0.5.4+2 \u003c0.6.0"

shelf_path "\u003e=0.1.0 \u003c0.2.0"

uri "\u003e=0.9.2 \u003c0.10.0"