Giter VIP home page Giter VIP logo

routingkit's Introduction

RoutingKit

Pub Version Test License Sponsors X (formerly Twitter) Follow

Routing Kit is a High-performance trie-node router.

  • High-performance:Based on Trie tree implementation, efficient performance.
  • Accurate:Using / to split trie-node nodes can accurately match routes.
  • Flexible:Support dynamic routing matching

Installation

Add the dependency to your pubspec.yaml file:

dependencies:
  routingkit: 0.2.0

Or install it with pub:

dart pub add routingkit
# or
flutter pub add routingkit

Sponsor RoutingKit

RoutingKit is an open source project based on the MIT license. If your Router implementation uses RoutingKit, or you find my work helpful to you, please sponsor me on GitHub Sponsors. Your support is my biggest motivation.

Getting Started

RoutingKit improves the performance of route matching and provides a simpler API. Here is a simple example:

import 'package:routingkit/routingkit.dart';

final router = TrieRouter();

router.register(0, '/users/:user_id'.asSegments);
router.register(1, '/users/:user_id/posts'.asSegments);
router.register(2, '/users/:user_id/posts/:post_id'.asSegments);

void main() {

  final zeroParams = Params();
  final zeroResult = router.lookup('/users/1'.asPaths, zeroParams);
  print(zeroResult); // 0
  print(zeroParams.keys); // {user_id}
  print(zoroParams.get('user_id')); // 1

  final oneParams = Params();
  final oneResult = router.lookup('/users/1/posts'.asPaths, oneParams);
  print(oneResult); // 1

  final twoParams = Params();
  final twoResult = router.lookup('/users/1/posts/2'.asPaths, twoParams);
  print(twoResult); // 2
  print(twoParams.keys); // {user_id, post_id}
  print(twoParams.get('user_id')); // 1
  print(twoParams.get('post_id')); // 2
}

Through the above example, you can see that the use of RoutingKit is very simple, just create a TrieRouter instance, then use the register method to register the route, and finally use the lookup method to route matching.

The Parameters class is a parameter container that will save the matched parameters internally after the route is successfully matched. For specific usage, please refer to Params.

Path Segments

Segment is a core concept in RoutingKit. It is an abstract class with four subclasses:

  • ConstSegment: Constant path component, for example /users.
  • ParamSegment: Parameter path component, for example /users/:user_id.
  • AnySegment: Wildcard path component, for example /users/*.
  • CatchallSegment: Catchall path component, for example /users/**.

Of course, you don’t have to care about these classes, because RoutingKit has provided you with some convenient methods, for example:

'/users'.asSegments; // [ConstSegment('users')]
'/users/:user_id'.asSegments; // [ConstSegment('users'), ParamSegment('user_id')]
'users'.asSegments // ConstSegment('users')
'/users/:id/*'.asSegments; // [ConstSegment('users'), ParamSegment('id'), AnySegment()]
'/users/**'.asSegments; // [ConstSegment('users'), CatchallSegment()]

You can also directly pass a string to the default constructor factory function of Segment, for example:

Segment('users'); // ConstSegment('users')
Segment(':user_id'); // ParamSegment('user_id')
Segment('*'); // AnySegment()
Segment('**'); // CatchallSegment()

At the same time, Segment also provides literal constructors and static properties:

Segment.constant('users'); // ConstSegment('users')
Segment.parma('user_id'); // ParamSegment('user_id')
Segment.any(); // AnySegment()
Segment.catchall(); // CatchallSegment()

Segment has only one property description, which is a string used to describe the literal definition of the current path component, for example:

Segment.constant('users').description; // users

ConstSegment

The ConstSegment is a constant path component, and its constant parameter is a constant string, for example:

final component = Segment.constant('users');

It returns a component that is a ConstSegment instance that represents the constant string that must be matched in the path segment, for example:

router.register(0, '/users'.asSegments);

final params = Params();
router.lookup('/users'.asPaths, params); // 0
router.lookup('/posts'.asPaths, params); // null

ParamSegment

The ParamSegment is a parameter path component, and its identifier parameter is a string used to represent the name of the current parameter, for example:

final component = Segment.param('user_id');

It returns a component that is a ParamSegment instance that represents the parameter that must be matched in the path segment, for example:

router.register(0, '/users/:user_id'.asSegments);

final params = Params();

router.lookup('/users/1'.asPaths, params); // 0
print(params.keys); // {user_id}
print(params.get('user_id')); // 1

AnySegment

The AnySegment is a path wildcard component that matches any string in the current path segment, for example:

router.register(0, '/users/:user_id/*'.asSegments);

final params = Params();

router.lookup('/users/1/posts'.asPaths, params); // 0
print(params.catchall); // (posts)

CatchallSegment

The CatchallSegment is a path capture component that matches all path segments defined after it, for example:

router.register(0, '/users/**'.asSegments);

final params = Params();

router.lookup('/users/1/posts'.asPaths, params); // 0
print(params.catchall); // (1, posts)

Parameters

Parameters is a parameter container that will save the matched parameters internally after the route is successfully matched, for example:

router.register(0, '/users/:user_id'.asSegments);

final params = Params();

router.lookup('/users/1'.asPaths, params); // 0

print(params.get('user_id')); // 1
print(params.keys); // {user_id}

get

Parameters provides the get method to get the parameter with the specified name, for example:

params.get('user_id'); // 1

getAll

Parameters provides the getAll method to get all parameters with the specified name, for example:

params.getAll('user_id'); // [1]

set

Parameters provides the set method to set the parameter with the specified name, for example:

params.set('user_id', '1');

RoutingKit saves the matched parameters in Parameters through the set method. You can also set more custom parameters through the set method, for example:

params.set('other', '1');

keys

The Parameters provides the keys property to get all parameter names, for example:

params.keys; // {user_id, other}

catchall

Parameters provides the catchall field to get the captured AnySegment or CatchallSegment parameter, for example:

router.register(0, '/users/:user_id/*'.asSegments);
router.register(1, '/posts/**'.asSegments);

final params = Params();

router.lookup('/users/1/posts'.asPaths, params); // 0
print(params.catchall); // (posts)

router.lookup('/posts/1/2/3'.asPaths, params); // 1
print(params.catchall); // (1, 2, 3)

setCatchall

The Parameters provides the set catchall method to set the captured AnySegment or CatchallSegment parameter. You can set the captured parameter by the set catchall method, for example:

router.register(0, '/users/:user_id/*'.asSegments);

final params = Params();

router.lookup('/users/1/posts'.asPaths, params); // 0
print(params.catchall); // (posts)

params.catchall = ['1', '2', '3'];
print(params.catchall); // (1, 2, 3)

Router

The Router is an interface class that has two abstract methods:

  • register: Register route.
  • lookup: Route matching.

In RoutingKit, TrieRouter is an implementation of Router. It is a router based on Trie tree. Its register method is used to register routes, and its lookup method is used for route matching.

register

register method is used to register routes, it has two parameters:

  • value: Route value, it is a generic parameter, specified by the generic parameter of Router<T>.
  • path: Route component, it is an Iterable<Segment> type parameter.

Example:

router.register(0, '/users/:user_id'.asSegments);

lookup

lookup method is used for route matching, it has two parameters:

  • path: 路由片段,它是一个 Iterable<String> 类型的参数。

  • parameters: 参数容器,它是一个 Parameters 类型的参数。

  • path: Route segment, it is an Iterable<String> type parameter.

  • parameters: Parameter container, it is a Parameters type parameter.

Example:

router.lookup('/users/1'.asPaths, Params());

Case sensitive

RoutingKit is case sensitive by default, you can set case sensitive through the caseSensitive parameter, for example:

final router = TrieRouter(
  caseSensitive: false, // False is case insensitive. default is true.
);

Benchmark

RoutingKit provides a benchmark test, you can find it in the benchmark/main.dart file, and its test results are as follows:

(caseSensitive: true) Routing match first(RunTime): 0.60953 us.
(caseSensitive: false) Routing match first(RunTime): 0.656843 us.
(caseSensitive: true) Routing match last(RunTime): 0.6479385 us.
(caseSensitive: false) Routing match last(RunTime): 0.7026445 us.
(caseSensitive: true) Routing minimum match(RunTime): 0.26883614654192156 us.
(caseSensitive: false) Routing minimum match(RunTime): 0.2979291527317985 us.
(caseSensitive: true) Router match early fail(RunTime): 0.22558736156240886 us.
(caseSensitive: false) Router match early fail(RunTime): 0.2578717881655905 us.

NOTE: The test result is run through the dart run benchmark/main.dart command, and the test environment is:

Dart SDK version: 3.2.3
OS: macOS 14.1.2 (23B92)
CPU: Apple M1
Memory: 8 GB

License

RoutingKit is open-sourced software licensed under the MIT license.

routingkit's People

Contributors

medz avatar renovate[bot] avatar dependabot[bot] avatar

Stargazers

 avatar mori yuta avatar Ming avatar  avatar

Watchers

 avatar  avatar

routingkit's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/test.yml
  • actions/checkout v4
  • dart-lang/setup-dart v1
pub
pubspec.yaml
  • logging ^1.2.0
  • benchmark_harness ^2.2.2
  • lints ^4.0.0
  • test ^1.24.0
  • dart ^3.2.0

  • Check this box to trigger a request for Renovate to run again on this repository

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.