Documentation Index Fetch the complete documentation index at: https://mintlify.com/MonishAMPT/fastroute-code/llms.txt
Use this file to discover all available pages before exploring further.
As your FastRoute application grows, organizing routes into separate files becomes essential for maintainability and team collaboration.
Why Organize Routes?
Maintainability Easier to find and update specific routes
Separation of Concerns Keep different types of routes logically separated
Team Collaboration Multiple developers can work on different route files
Scalability Add new features without cluttering existing files
Route File Pattern
FastRoute uses a simple pattern for organizing routes into separate files:
Create route files that return a closure
The closure accepts a RouteCollector instance
Load and call the closure in your main dispatcher
Loading Route Files
In your main index.php, load route files using require and call them:
$dispatcher = FastRoute\ simpleDispatcher ( function ( RouteCollector $r ) {
// Load API routes
$apiRoutes = require __DIR__ . '/routes/api.php' ;
$apiRoutes ( $r );
// Load web routes
$webRoutes = require __DIR__ . '/routes/web.php' ;
$webRoutes ( $r );
});
The require statement returns the value from the route file (a closure), which is then called with the RouteCollector instance.
Creating Route Files
API Routes File
Create routes/api.php that returns a closure:
<? php
use FastRoute\ RouteCollector ;
use FastRoute\ ConfigureRoutes ;
include __DIR__ . "/../v1/test.php" ;
$obj = new testing ;
return function ( RouteCollector $r ) {
$obj = new testing ;
$r -> addGroup ( '/api/projects' , function ( FastRoute\ RouteCollector $r ) use ( $obj ) {
$r -> get ( '/testing/test' , function () use ( $obj ) {
$obj -> hello ();
});
$r -> get ( "/" , function () use ( $obj ) {
$obj -> display ( 1 );
});
});
$r -> addRoute ( 'GET' , '/api/test' , 'test_get' );
$r -> addRoute ( 'POST' , '/api/test' , 'test_post' );
};
Web Routes File
Create routes/web.php for HTML-returning routes:
<? php
use FastRoute\ RouteCollector ;
return function ( RouteCollector $r ) {
$r -> get ( '/' , function () {
require __DIR__ . '/../views/main.php' ;
});
$r -> get ( '/about' , function () {
require __DIR__ . '/../views/about.php' ;
});
};
Advanced Organization Patterns
Organizing by Feature
For larger applications, organize routes by feature:
routes/
├── api/
│ ├── users.php
│ ├── products.php
│ └── orders.php
├── web/
│ ├── public.php
│ └── admin.php
└── index.php
Create a loader file:
<? php
use FastRoute\ RouteCollector ;
return function ( RouteCollector $r ) {
// Load user routes
$userRoutes = require __DIR__ . '/users.php' ;
$userRoutes ( $r );
// Load product routes
$productRoutes = require __DIR__ . '/products.php' ;
$productRoutes ( $r );
// Load order routes
$orderRoutes = require __DIR__ . '/orders.php' ;
$orderRoutes ( $r );
};
Organizing by Version
For APIs with versioning:
routes/
├── api/
│ ├── v1/
│ │ ├── users.php
│ │ └── products.php
│ └── v2/
│ ├── users.php
│ └── products.php
└── web.php
<? php
use FastRoute\ RouteCollector ;
return function ( RouteCollector $r ) {
$r -> addGroup ( '/api/v1/users' , function ( RouteCollector $r ) {
$r -> get ( '/' , 'v1_list_users' );
$r -> get ( '/{id:\d+}' , 'v1_get_user' );
$r -> post ( '/' , 'v1_create_user' );
});
};
Sharing Dependencies
When route files need to share dependencies (like class instances), you have several options:
Option 1: Include at File Level
include __DIR__ . "/../v1/test.php" ;
$obj = new testing ;
return function ( RouteCollector $r ) {
$obj = new testing ;
$r -> get ( '/api/class' , function () use ( $obj ) {
$obj -> hello ();
});
};
Option 2: Dependency Injection Container
For larger applications, consider using a DI container:
// Create container
$container = new \Pimple\ Container ();
$container [ 'testing' ] = function () {
return new testing ();
};
// Pass to route files
$apiRoutes = require __DIR__ . '/routes/api.php' ;
$apiRoutes ( $r , $container );
Option 3: Global Registry
For simple cases, use a registry pattern:
class Registry {
private static $instances = [];
public static function set ( $key , $instance ) {
self :: $instances [ $key ] = $instance ;
}
public static function get ( $key ) {
return self :: $instances [ $key ] ?? null ;
}
}
Route File Structure
Every route file should follow this structure:
<? php
// 1. Import necessary classes
use FastRoute\ RouteCollector ;
// 2. Load dependencies (if needed)
include __DIR__ . '/../handlers/UserHandler.php' ;
// 3. Create instances (if needed)
$handler = new UserHandler ();
// 4. Return closure that registers routes
return function ( RouteCollector $r ) use ( $handler ) {
// 5. Define routes
$r -> addGroup ( '/api/users' , function ( RouteCollector $r ) use ( $handler ) {
$r -> get ( '/' , function () use ( $handler ) {
$handler -> list ();
});
$r -> get ( '/{id:\d+}' , function ( $vars ) use ( $handler ) {
$handler -> get ( $vars [ 'id' ]);
});
});
};
This consistent structure makes it easy for team members to understand and maintain route files.
Complete Example
Here’s how the complete routing system works together:
Main Entry Point
<? php
require 'vendor/autoload.php' ;
use FastRoute\ RouteCollector ;
$request_uri = $_SERVER [ 'REQUEST_URI' ];
$method = $_SERVER [ 'REQUEST_METHOD' ];
$cleaned_uri = str_replace ( '/apitest' , '' , $request_uri );
$uri = parse_url ( $cleaned_uri , PHP_URL_PATH );
$dispatcher = FastRoute\ simpleDispatcher ( function ( RouteCollector $r ) {
// Load API routes
$apiRoutes = require __DIR__ . '/routes/api.php' ;
$apiRoutes ( $r );
// Load web routes
$webRoutes = require __DIR__ . '/routes/web.php' ;
$webRoutes ( $r );
});
$routeInfo = $dispatcher -> dispatch ( $method , $uri );
if ( strpos ( $uri , '/api/' ) === 0 ) {
header ( 'Content-Type: application/json; charset=utf-8' );
} else {
header ( 'Content-Type: text/html; charset=utf-8' );
}
switch ( $routeInfo [ 0 ]) {
case FastRoute\ Dispatcher :: NOT_FOUND :
header ( "HTTP/1.1 404 Not Found" );
echo json_encode ([ "message" => "Route not found" ]);
break ;
case FastRoute\ Dispatcher :: METHOD_NOT_ALLOWED :
header ( "HTTP/1.1 405 Method Not Allowed" );
echo json_encode ([ "message" => "Method not allowed" ]);
break ;
case FastRoute\ Dispatcher :: FOUND :
$handler = $routeInfo [ 1 ];
$var = $routeInfo [ 2 ];
call_user_func ( $handler , $var );
break ;
}
Best Practices
Each route file should handle a single resource or feature area. Don’t mix unrelated routes.
Name route files after the resources they handle (e.g., users.php, products.php).
Add comments to describe complex routes or special requirements: // Requires authentication token in header
$r -> get ( '/api/users/{id}' , 'get_user' );
Scaling Considerations
For Small Projects (< 50 routes)
Use 2-3 route files (api.php, web.php)
Keep handlers in main file or simple classes
For Medium Projects (50-200 routes)
Organize by feature (users, products, orders)
Use class-based handlers
Consider versioning for APIs
For Large Projects (200+ routes)
Organize by feature AND version
Use dependency injection
Implement middleware pattern
Consider route caching
Next Steps
Project Structure Review the recommended project structure
Route Handlers Learn about different handler types
API Routes Create organized API endpoints
Web Routes Organize your web routes effectively