2021-09-25 06:32:32 +00:00
# Angel3 Route
![Pub Version (including pre-releases) ](https://img.shields.io/pub/v/angel3_route?include_prereleases )
2021-05-14 07:02:50 +00:00
[![Null Safety ](https://img.shields.io/badge/null-safety-brightgreen )](https://dart.dev/null-safety)
2021-05-15 06:01:47 +00:00
[![Gitter ](https://img.shields.io/gitter/room/angel_dart/discussion )](https://gitter.im/angel_dart/discussion)
2021-09-25 06:32:32 +00:00
[![License ](https://img.shields.io/github/license/dukefirehawk/angel )](https://github.com/dukefirehawk/angel/tree/master/packages/route/LICENSE)
2016-11-23 09:13:42 +00:00
2021-09-25 06:32:32 +00:00
A powerful, isomorphic routing library for Dart.
2016-11-23 09:13:42 +00:00
2021-09-25 06:32:32 +00:00
`angel3_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.
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
`angel3_route` does not require the use of [Angel 3 ](https://pub.dev/packages/angel3_framework ), and has minimal dependencies. Thus, it can be used in any application, regardless of framework. This includes Web apps, Flutter apps, CLI apps, and smaller servers which do not need all the features of the Angel framework.
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
## Contents
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
- [Angel3 Route ](#angel3-route )
- [Contents ](#contents )
- [Examples ](#examples )
- [Routing ](#routing )
- [Hierarchy ](#hierarchy )
- [In the Browser ](#in-the-browser )
- [Route State ](#route-state )
- [Route Parameters ](#route-parameters )
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
## Examples
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
### Routing
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
If you use [Angel 3 ](https://pub.dev/packages/angel3_framework ), every `Angel` instance is a `Router` in itself.
2016-10-12 17:58:32 +00:00
```dart
2021-09-25 06:32:32 +00:00
void 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);
});
2016-10-19 22:04:06 +00:00
}, middleware: [put, middleware, here]);
2019-11-28 17:46:57 +00:00
// Grouping can also take async callbacks.
await router.groupAsync('/hello', (router) async {
var name = await getNameFromFileSystem();
router.get(name, (req, res) => '...');
});
2016-10-12 17:58:32 +00:00
}
```
2021-09-25 06:32: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.
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
### Hierarchy
2016-10-12 17:58:32 +00:00
```dart
2021-09-25 06:32:32 +00:00
void 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.
2021-09-25 06:32:32 +00:00
## In the Browser
Supports both hashed routes and pushState. The `BrowserRouter` interface exposes a `Stream<RoutingResult> onRoute` , which can be listened to for changes. It will fire `"NULL"` whenever no route is matched.
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
`angel3_route` will also automatically intercept `<a>` elements and redirect them to your routes.
2016-10-12 17:58:32 +00:00
To prevent this for a given anchor, do any of the following:
2021-09-25 06:32:32 +00:00
* Do not provide an `href`
* Provide a `download` or `target` attribute on the element
* Set `rel="external"`
2016-10-12 17:58:32 +00:00
2021-09-25 06:32:32 +00:00
## Route State
2016-10-12 17:58:32 +00:00
```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
}
```
2021-09-25 06:32:32 +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` .
## Route Parameters
2016-11-27 22:24:30 +00:00
2021-09-25 06:32:32 +00:00
Routes can have parameters, as seen in the above examples. Use `allParams` in a `RoutingResult` to get them as a nice `Map` :
2017-06-01 12:47:16 +00:00
```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'};
```