Last updated:
0 purchases
route tree
RouteTree #
A generic library for parsing URI paths.
RouteTree is a generic routing library that makes it easy to implement routing logic based on the path segments of a URI. This is done by nesting Segment nodes to build a tree not unlike the Widget trees you see in Flutter apps.
Quick example #
final router = Segment.root<String>(
create: (context) => "home",
createError: (context) => "Error!",
children: [
Segment.path(
name: "first_path",
create: (context) => "routed to first_path",
),
Segment.path(
name: "second_path",
create: (context) => "routed to second_path",
children: [
Segment.param(
parser: const UintParser("id"),
create: (context) => "routed to /second_path/${context["id"]}",
),
],
),
],
);
assert(router.route(Uri.parse("/second_path/12")) == "routed to second_path/12");
copied to clipboard
Note the template parameter that denotes what data type RootSegment.route will return. This makes route_tree so flexible.
How it works #
The basic building blocks of this library are Segments, SegmentParsers and the ParseContext.
Segments #
Segments are to route_tree what Widgets are to Flutter. Each Segment represents a possible path segment that can be part of a route. Since it's templated it can be used in several ways, like routing in a Flutter app or choosing the correct function to handle incoming HTTP requests in a backend. The abstract class Segment contains several factory constructors to make finding the right one easier.
RootSegment or Segment.root
The root node of any route_tree.
Defines the "/"-route, the root error-handler as well as a list of SegmentVerifiers that can be used to assert certain properties of the route_tree.
By default RootSegments contain findConflictingParamKeys, which returns an error if your route_tree contains duplicate parameter keys like /users/{id}/edit/{id}.
/// Matches "/"
final router = Segment.root<String>(
create: (context) => "home",
createError: (context) => "root error",
children: [
...
],
);
copied to clipboard
PathSegment or Segment.path
The Segment you're probably gonna use most often. It defines a simple literal path segment. Internally children of a Segment with a LiteralParser (which by default only applies to PathSegments) are contained in a Map<String, PathSegment> for constant time lookup of corresponding path segments.
Segment.root<String>(
...
children: [
/// Matches "/about"
Segment.path(
name: "about",
create: (context) => "about",
),
/// Matches "/settings/*", but not "/settings" itself, since [create] was
/// left null
Segment.path(
name: "settings",
children: [
/// Matches "/settings/privacy"
Segment.path(
name: "privacy",
create: (context) => "privacy",
),
],
),
],
);
copied to clipboard
RegExpPathSegment or Segment.regExpPath
Used to define one or (usually) more paths that should be matched by one Segment using a regular expression.
Segment.root<String>(
...
children: [
/// Matches any path segment consisting of letters
Segment.regExpPath(
regExp: RegExp(r"[a-zA-Z]+"),
create: (context) => "letter path",
),
],
);
copied to clipboard
ParamSegment or Segment.param
Used to define a path parameter. If the segment of a URI is matched, the matched value is added to the ParseContext, from which it can be queried using ParseContext.operator[]
Segment.root<String>(
create: (context) => "home",
createError: (context) => "error!",
children: [
/// Matches "/users/*", since [create] was left null
Segment.path(
name: "users",
children: [
/// Matches "/users/{id}", where {id} is any non-negative integer as defined
/// by [UintParser].
Segment.param(
parser: const UintParser("id"),
create: (context) => context["id"] as String,
),
],
),
],
);
copied to clipboard
RegExpParamSegment or Segment.regExpParam
Consider URLs used by Twitter where a URL like https://twitter.com/{name}, where name can be any word and a hypothetical Twitter client obviously couldn't hardcode all possible names. This is where this Segment comes into play. It can be used to define a path parameter that matches the provided regular expression and injects it into the ParseContext, from which it can be queried using ParseContext.operator[].
final router = Segment.root<String>(
create: (context) => "home",
createError: (context) => "error!",
children: [
/// Matches any path segment consisting of letters
Segment.regExpParam(
parser: RegExpParamParser.forward(
key: "name",
regExp: RegExp(r"\w+"),
),
create: (context) => context["name"] as String,
),
],
);
assert(router.route(Uri.parse("/flutterdev")) == "flutterdev");
copied to clipboard
SegmentParsers #
The actual parsing logic for looking up correct segments is delegated to instances of SegmentParser. The predefined parsers are:
SegmentParser.withFunction, which takes a Parser function and can be used to quickly define custom SegmentParses
LiteralParser, which is primarily used by PathSegment (& Segment.path) and matches a path segment literally
RegExpParser, which matches a path segment against a regular expression
ParamParser, subclass of SegmentParser and base class of parsers that inject matches into the ParseContext
ParamParser.withFunction, which can be used to quickly define custom ParamParsers
RegExpPararamParser, similar to RegExpParser, but also injects a successful match into the ParseContext
IntParser & UintParser, which match integers and non-negative integers respectively. The latter is useful for for id path parameters.
ParseContext #
The ParseContext holds the initial URI as well as any path parameters in the current route. It is passed to the create-function when they're called after a path has been matched.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.