Routing

Advanced routing with authentication, permissions, and dynamic paths

Routing in WebApp Package

WebApp provides a powerful and flexible routing system with built-in support for authentication, permissions, nested routes, and dynamic path handling.

Basic Routing Structure

The getWebRoute function returns a list of routes that define how your application handles incoming requests:

Future<List<WebRoute>> getWebRoute(WebRequest rq) async {
  final homeController = HomeController(rq);
  final includeController = IncludeJsController(rq);
  final authController = AuthController(rq);

  var paths = [
    WebRoute(
      path: 'ws',
      methods: RequestMethods.ALL,
      rq: rq,
      index: homeController.socket,
    ),
    WebRoute(
      path: 'app/includes.js',
      methods: RequestMethods.ALL,
      rq: rq,
      index: includeController.index,
    ),
    WebRoute(
      path: 'example',
      rq: rq,
      index: () => rq.redirect('/'),
      ports: [80, 8080, 443],                    // Allowed ports
      hosts: ['localhost', '127.0.0.1', 'example.com'], // Allowed hostnames
      children: [
        WebRoute(
          path: '/form',
          methods: RequestMethods.ALL,
          rq: rq,
          index: homeController.exampleForm,
        ),
        WebRoute(
          path: '/cookie',
          methods: RequestMethods.ONLY_GET,
          rq: rq,
          index: homeController.exampleCookie,
        ),
        WebRoute(
          path: '/panel',
          methods: RequestMethods.ONLY_GET,
          rq: rq,
          index: homeController.examplePanel,
          auth: authController,
        ),
      ],
    ),
    WebRoute(
      path: 'info',
      extraPath: ['api/info'],
      rq: rq,
      index: homeController.info,
    ),
  ];

  return [
    WebRoute(
      path: '/',
      rq: rq,
      methods: RequestMethods.ALL,
      controller: homeController,
      children: [
        ...paths,
        WebRoute(
          path: 'fa/*',
          extraPath: [
            'en/*',
            'nl/*',
          ],
          rq: rq,
          index: homeController.changeLanguage,
        )
      ],
    ),
  ];
}

Route Features

1. Request Methods

Control which HTTP methods a route accepts:

WebRoute(
  path: 'api/users',
  methods: RequestMethods.ONLY_GET,  // Only GET requests
  rq: rq,
  index: userController.getUsers,
)

WebRoute(
  path: 'api/users',
  methods: RequestMethods.ONLY_POST, // Only POST requests
  rq: rq,
  index: userController.createUser,
)

WebRoute(
  path: 'dashboard',
  methods: RequestMethods.ALL,       // All HTTP methods
  rq: rq,
  index: dashboardController.index,
)

2. Authentication and Authorization

Protect routes with authentication and permissions:

WebRoute(
  path: 'admin/panel',
  rq: rq,
  index: adminController.panel,
  auth: authController,              // Requires authentication
  permissions: ['admin', 'moderator'], // Required permissions
)

3. Host and Port Restrictions

Restrict routes to specific hosts and ports:

WebRoute(
  path: 'api/internal',
  rq: rq,
  index: internalController.index,
  ports: [8080, 8443],              // Only these ports
  hosts: ['localhost', '127.0.0.1'], // Only these hosts
)

4. Dynamic Paths and Wildcards

Handle dynamic paths with wildcards:

WebRoute(
  path: 'user/*',                    // Matches /user/anything
  rq: rq,
  index: userController.profile,
)

WebRoute(
  path: 'lang/*',
  extraPath: ['locale/*'],           // Additional path patterns
  rq: rq,
  index: localeController.change,
)

5. Nested Routes

Organize routes hierarchically:

WebRoute(
  path: 'api',
  rq: rq,
  children: [
    WebRoute(
      path: 'v1',
      rq: rq,
      children: [
        WebRoute(
          path: 'users',
          rq: rq,
          index: userController.list,
        ),
        WebRoute(
          path: 'posts',
          rq: rq,
          index: postController.list,
        ),
      ],
    ),
  ],
)

6. Controllers

Associate entire controllers with routes:

WebRoute(
  path: 'blog',
  rq: rq,
  controller: blogController,        // Use controller for this route tree
  children: [
    // Child routes inherit the controller
  ],
)

Route Parameters

Access route parameters in your controllers:

class UserController extends WaController {
  Future<void> profile() async {
    String? userId = rq.params['id'];
    String? action = rq.params['action'];
    
    // Handle the request based on parameters
  }
}

Redirects

Perform redirects within routes:

WebRoute(
  path: 'old-path',
  rq: rq,
  index: () => rq.redirect('/new-path'),
)

Request Methods Enum

Available request method options:

  • RequestMethods.ALL - Accept all HTTP methods
  • RequestMethods.ONLY_GET - Only GET requests
  • RequestMethods.ONLY_POST - Only POST requests
  • RequestMethods.ONLY_PUT - Only PUT requests
  • RequestMethods.ONLY_DELETE - Only DELETE requests
  • RequestMethods.ONLY_PATCH - Only PATCH requests

Best Practices

  1. Organize by Feature: Group related routes under common parent paths
  2. Use Controllers: Leverage controllers for organized code structure
  3. Secure Sensitive Routes: Always add authentication for protected areas
  4. Validate Permissions: Use granular permissions for role-based access
  5. Handle Errors: Implement proper error handling in route handlers
  6. Document Routes: Keep route documentation up to date

Next Steps