platform/README.md

142 lines
4.1 KiB
Markdown
Raw Normal View History

2016-10-11 18:53:32 +00:00
# angel_route
2016-11-23 09:13:42 +00:00
2017-08-03 16:14:21 +00:00
[![Pub](https://img.shields.io/pub/v/angel_route.svg)](https://pub.dartlang.org/packages/angel_route)
2018-08-21 19:00:04 +00:00
[![build status](https://travis-ci.org/angel-dart/route.svg)](https://travis-ci.org/angel-dart/route)
2016-11-23 09:13:42 +00:00
2016-10-12 17:58:32 +00:00
A powerful, isomorphic routing library for Dart.
This API is a huge improvement over the original [Angel](https://github.com/angel-dart/angel)
routing system, and thus deserves to be its own individual project.
`angel_route` exposes a routing system that takes the shape of a tree. This tree structure
can be easily navigated, in a fashion somewhat similar to a filesystem. The `Router` API
is a very straightforward interface that allows for your code to take a shape similar to
the route tree. Users of Laravel and Express will be very happy.
`angel_route` does not require the use of [Angel](https://github.com/angel-dart/angel),
2018-08-20 19:00:16 +00:00
and has minimal dependencies. Thus, it can be used in any application, regardless of
2016-10-12 17:58:32 +00:00
framework. This includes Web apps, Flutter apps, CLI apps, and smaller servers which do
not need all the features of the Angel framework.
# Contents
* [Examples](#examples)
* [Routing](#routing)
* [Tree Hierarchy and Path Resolution](#hierarchy)
* [In the Browser](#in-the-browser)
* [Route State](#route-state)
* [Route Parameters](#route-parameters)
# Examples
## Routing
If you use [Angel](https://github.com/angel-dart/angel), every `Angel` instance is
a `Router` in itself.
```dart
main() {
2019-11-28 17:40:32 +00:00
final router = Router();
2016-10-12 17:58:32 +00:00
router.get('/users', () {});
router.post('/users/:id/timeline', (String id) {});
2016-10-13 09:52:56 +00:00
router.get('/square_root/:id([0-9]+)', (n) {
2016-11-27 23:39:03 +00:00
return { 'result': pow(int.parse(n), 0.5) };
2016-10-12 17:58:32 +00:00
});
2018-08-20 14:24:11 +00:00
// You can also have parameters auto-parsed.
//
// Supports int, double, and num.
router.get('/square_root/int:id([0-9]+)', (int n) {
return { 'result': pow(n, 0.5) };
});
2016-10-12 17:58:32 +00:00
router.group('/show/:id', (router) {
router.get('/reviews', (id) {
return someQuery(id).reviews;
});
// Optionally restrict params to a RegExp
router.get('/reviews/:reviewId([A-Za-z0-9_]+)', (id, reviewId) {
return someQuery(id).reviews.firstWhere(
(r) => r.id == reviewId);
});
}, middleware: [put, middleware, here]);
2016-10-12 17:58:32 +00:00
}
```
The default `Router` does not give any notification of routes being changed, because
there is no inherent stream of URL's for it to listen to. This is good, because a server
needs a lot of flexibility with which to handle requests.
## Hierarchy
```dart
main() {
2019-11-28 17:40:32 +00:00
final router = Router();
2016-10-12 17:58:32 +00:00
2016-11-27 22:24:30 +00:00
router
.chain('middleware1')
.chain('other_middleware')
.get('/hello', () {
print('world');
});
2016-10-12 17:58:32 +00:00
router.group('/user/:id', (router) {
router.get('/balance', (id) async {
final user = await someQuery(id);
return user.balance;
});
});
}
```
See [the tests](test/route/no_params.dart) for good examples.
# In the Browser
Supports both hashed routes and pushState. The `BrowserRouter` interface exposes
2016-11-27 22:24:30 +00:00
a `Stream<RoutingResult> onRoute`, which can be listened to for changes. It will fire `null`
2016-10-12 17:58:32 +00:00
whenever no route is matched.
`angel_route` will also automatically intercept `<a>` elements and redirect them to
your routes.
To prevent this for a given anchor, do any of the following:
* Do not provide an `href`
* Provide a `download` or `target` attribute on the element
* Set `rel="external"`
# Route State
```dart
main() {
2019-11-28 17:40:32 +00:00
final router = BrowserRouter();
2016-10-12 17:58:32 +00:00
// ..
router.onRoute.listen((route) {
if (route == null)
throw 404;
2016-10-13 20:50:27 +00:00
else route.state['foo'] = 'bar';
2016-10-12 17:58:32 +00:00
});
2017-03-20 19:46:54 +00:00
router.listen(); // Start listening
2016-10-12 17:58:32 +00:00
}
```
2016-11-27 22:24:30 +00:00
For applications where you need to access a chain of handlers, consider using
`onResolve` instead. You can see an example in `web/shared/basic.dart`.
2016-10-12 17:58:32 +00:00
# Route Parameters
Routes can have parameters, as seen in the above examples.
2017-06-01 12:47:16 +00:00
Use [allParams](https://www.dartdocs.org/documentation/angel_route/1.0.3/angel_route/RoutingResult-class.html)
in a `RoutingResult` to get them as a nice `Map`:
```dart
2019-11-28 17:40:32 +00:00
var router = Router();
2017-06-01 12:47:16 +00:00
router.get('/book/:id/authors', () => ...);
var result = router.resolve('/book/foo/authors');
var params = result.allParams; // {'id': 'foo'};
```