Logodart_express

Routing#

dart_express uses a fast radix-tree router to match incoming requests to handlers.

Basic Routes#

Define routes for different HTTP methods:

final app = DartExpress();

app.get('/users', (req, res) {
  res.json({'users': []});
});

app.post('/users', (req, res) async {
  final body = await req.body;
  res.status(201).json(body);
});

app.put('/users/:id', (req, res) {
  res.json({'updated': req.params['id']});
});

app.delete('/users/:id', (req, res) {
  res.status(204).send();
});

Path Parameters#

Capture dynamic segments from the URL:

app.get('/users/:userId/posts/:postId', (req, res) {
  final userId = req.params['userId'];
  final postId = req.params['postId'];
  
  res.json({
    'userId': userId,
    'postId': postId,
  });
});

Access via: /users/123/posts/456

Query Parameters#

Access query string parameters:

app.get('/search', (req, res) {
  final query = req.query['q'];
  final page = int.tryParse(req.query['page'] ?? '1') ?? 1;
  
  res.json({
    'query': query,
    'page': page,
    'results': [],
  });
});

Access via: /search?q=dart&page=2

Wildcard Routes#

Match multiple path segments:

app.get('/files/*', (req, res) {
  final filePath = req.params['*'];
  res.text('File path: $filePath');
});

Access /files/documents/report.pdf → captures documents/report.pdf

Route Groups#

Organize routes with common prefixes:

// API v1 routes
app.get('/api/v1/users', getUsersV1);
app.get('/api/v1/posts', getPostsV1);

// API v2 routes
app.get('/api/v2/users', getUsersV2);
app.get('/api/v2/posts', getPostsV2);

Route Order#

Routes are matched in the order they're defined:

// Specific route first
app.get('/users/me', (req, res) {
  res.json({'user': 'current user'});
});

// Generic route second
app.get('/users/:id', (req, res) {
  res.json({'user': req.params['id']});
});

Controllers#

Organize related routes in controllers:

class UserController {
  void getAll(Request req, Response res) {
    res.json({'users': []});
  }
  
  void getById(Request req, Response res) {
    res.json({'id': req.params['id']});
  }
  
  Future<void> create(Request req, Response res) async {
    final body = await req.body;
    res.status(201).json(body);
  }
}

void main() {
  final app = DartExpress();
  final users = UserController();
  
  app.get('/users', users.getAll);
  app.get('/users/:id', users.getById);
  app.post('/users', users.create);
}

Method Chaining#

Chain multiple route handlers:

app
  .get('/users', getAllUsers)
  .post('/users', createUser)
  .put('/users/:id', updateUser)
  .delete('/users/:id', deleteUser);

All Methods#

Handle any HTTP method:

app.all('/api/*', (req, res, next) async {
  print('API called: ${req.method} ${req.uri.path}');
  await next();
});

Regular Expressions#

For complex patterns, routes use glob syntax internally:

app.get('/users/:id', handler);        // :id matches any segment
app.get('/files/*', handler);          // * matches multiple segments

Performance#

The radix tree router provides:

  • O(log n) lookup time
  • Efficient matching even with thousands of routes
  • Zero allocations for route matching