platform/packages/route/README.md

146 lines
4.2 KiB
Markdown
Raw Normal View History

2021-05-14 07:02:50 +00:00
# angel3_route
[![version](https://img.shields.io/badge/pub-v2.12.4-brightgreen)](https://pub.dartlang.org/packages/angel3_route)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
2016-11-23 09:13:42 +00:00
2021-05-14 07:02:50 +00:00
[![License](https://img.shields.io/github/license/dukefirehawk/angel)](https://github.com/dukefirehawk/angel/tree/angel3/route)
2016-11-23 09:13:42 +00:00
2016-10-12 17:58:32 +00:00
2021-05-14 07:02:50 +00:00
A powerful, isomorphic routing library for Dart.
2016-10-12 17:58:32 +00:00
2021-05-14 07:02:50 +00:00
`angel3_route` exposes a routing system that takes the shape of a tree. This tree structure
2016-10-12 17:58:32 +00:00
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.
2021-05-14 07:02:50 +00:00
`angel3_route` does not require the use of [Angel](https://github.com/dukefirehawk/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
2021-05-14 07:02:50 +00:00
If you use [Angel](https://github.com/dukefirehawk/angel), every `Angel` instance is
2016-10-12 17:58:32 +00:00
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]);
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
}
```
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
2021-05-14 07:02:50 +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.
2021-05-14 07:02:50 +00:00
`angel3_route` will also automatically intercept `<a>` elements and redirect them to
2016-10-12 17:58:32 +00:00
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.
2021-05-14 07:02:50 +00:00
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'};
```