Basics / Routes

Routing Basics

Archery provides a modern, fluent routing API heavily inspired by Laravel. At the core is the Router class, which dispatches requests based on path and HTTP method, supporting dynamic type-coerced parameters, middleware pipelines, and nested route groups.

By default, routes are registered in your route scaffold files: lib/src/http/routes/web.dart and lib/src/http/routes/api.dart.

Basic Routing

The most basic Archery routes accept a URI and an asynchronous closure (handler). The closure receives an HttpRequest object and is expected to return it or a response helper.

import 'package:archery/archery/archery.dart';

void webRoutes(Router router) {
  router.get('/', (request) async {
    return request.view('welcome');
  });

  router.post('/submit', (request) async {
    // Process form
    return request.redirectHome();
  });
}

Available router methods match standard HTTP verbs: getpostputpatch, and delete.

Route Parameters

Archery routes can capture segments of the URI. Dynamic parameters are enclosed in curly braces {} and specify a data type.

Supported parameter types: stringintdouble, and uuid.

router.get('/users/{id:int}', (request) async {
  // Safe extraction! id is guaranteed to be an integer.
  final userId = RouteParams.get<int>('id');
  
  return request.json({'user_id': userId});
});

router.get('/posts/{slug:string}', (request) async {
  final slug = RouteParams.get<String>('slug');
  return request.json({'slug': slug});
});

Using RouteParams, Archery injects the captured values seamlessly into the Zone of the executing handler. If the route {id:int} is accessed as /users/abc, it will automatically fail to match and proceed to a 404 Not Found.

Route Groups

Route groups allow you to share path prefixes or middleware across a large number of routes without needing to define them on each individual route.

Path Prefixes

To group routes with a common URL prefix, use the group method:

router.group(
  prefix: '/admin',
  routes: () {
    router.get('/dashboard', (request) async {
      // Matches /admin/dashboard
    });
    
    router.get('/settings', (request) async {
      // Matches /admin/settings
    });
  },
);

Middleware Groups

You can apply an array of middleware to all routes within a group.

router.group(
  middleware: [Sessions.middleware, authMiddleware],
  routes: () {
    router.get('/profile', (request) async {
      // This route requires authentication
    });
  },
);

You can seamlessly combine prefixes and middleware:

router.group(
  prefix: '/api/v1',
  middleware: [apiRateLimiter],
  routes: () {
    // Defines /api/v1/users equipped with the API rate limiter
    router.get('/users', (request) async {
      return request.json([...]);
    });
  },
);

Form Method Spoofing

HTML forms do not support PUTPATCH, or DELETE actions. Therefore, when defining those routes that are called from an HTML form, you will need to add a hidden _method field to the form.

The Archery router will automatically look for the _method query parameter or body field and spoof the HTTP verb accordingly.