Quickstart Guide
Get your FastRoute application up and running with working routes in just a few minutes.
Creating the Main Router
Let’s start by setting up the main routing file that will handle all incoming requests.
Create index.php
Create your main entry point with the FastRoute dispatcher: <? php
// Autoload Composer dependencies
require 'vendor/autoload.php' ;
use FastRoute\ RouteCollector ;
// Get request information
$request_uri = $_SERVER [ 'REQUEST_URI' ];
$method = $_SERVER [ 'REQUEST_METHOD' ];
// Parse the URI path
$uri = parse_url ( $request_uri , PHP_URL_PATH );
// Create the dispatcher
$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 );
});
// Dispatch the current request
$routeInfo = $dispatcher -> dispatch ( $method , $uri );
This structure separates route definitions into different files, making your application easier to maintain.
Handle Route Responses
Add response handling based on the routing result: // Set appropriate content type
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 :
// Route not found
header ( "HTTP/1.1 404 Not Found" );
echo json_encode ([ "message" => "Route not found" ]);
break ;
case FastRoute\ Dispatcher :: METHOD_NOT_ALLOWED :
// Method not allowed
header ( "HTTP/1.1 405 Method Not Allowed" );
echo json_encode ([ "message" => "Method not allowed" ]);
break ;
case FastRoute\ Dispatcher :: FOUND :
// Route found, call the handler
$handler = $routeInfo [ 1 ];
$vars = $routeInfo [ 2 ];
call_user_func ( $handler , $vars );
break ;
}
Create Web Routes
Create routes/web.php for your web application 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' ;
});
};
Web routes return a function that receives the RouteCollector, keeping route definitions clean and modular.
Create API Routes
Create routes/api.php for your REST API endpoints: <? php
use FastRoute\ RouteCollector ;
return function ( RouteCollector $r ) {
// Simple GET endpoint
$r -> addRoute ( 'GET' , '/api/test' , 'test_get' );
// POST endpoint
$r -> addRoute ( 'POST' , '/api/test' , 'test_post' );
// Resource endpoints
$r -> addRoute ( 'GET' , '/api/items' , 'items_get' );
$r -> addRoute ( 'POST' , '/api/items' , 'items_post' );
// Route with parameters
$r -> get ( '/api/test/{id:\d+}/test/{id2:\d+}' , 'getid' );
// DELETE endpoint with parameter
$r -> delete ( '/api/test/delete/{id:\d+}' , 'delete' );
};
Route parameters use regex patterns like {id:\d+} to validate input. The \d+ pattern ensures the parameter is numeric.
Define Route Handlers
Add handler functions to index.php (after the switch statement): // Handlers for the routes
function test_get () {
echo json_encode ([ "message" => "This is the test route (GET)" ]);
}
function test_post () {
$data = json_decode ( file_get_contents ( 'php://input' ), true );
echo json_encode ([ "message" => "POST request received" , "data" => $data ]);
}
function items_get () {
echo json_encode ([ "items" => [ "item1" , "item2" , "item3" ]]);
}
function items_post () {
$data = json_decode ( file_get_contents ( 'php://input' ), true );
echo json_encode ([ "message" => "Item created" , "item" => $data ]);
}
function getid ( $vars ) {
$id = $vars [ 'id' ];
$id2 = $vars [ 'id2' ];
echo json_encode ([ "id" => $id , "id2" => $id2 ]);
}
function delete ( $vars ) {
echo json_encode ([ "message" => "Deleted item" , "id" => $vars [ 'id' ]]);
}
Using Route Groups
For better organization, you can group related routes with a common prefix:
$r -> addGroup ( '/api/projects' , function ( FastRoute\ RouteCollector $r ) {
$r -> get ( '/' , function () {
echo json_encode ([ "message" => "List all projects" ]);
});
$r -> get ( '/testing/test' , function () {
echo json_encode ([ "message" => "Testing endpoint" ]);
});
});
$r -> addGroup ( '/api/tasks' , function ( FastRoute\ RouteCollector $r ) {
$r -> get ( '/' , function () {
echo json_encode ([ "message" => "List all tasks" ]);
});
});
Route groups are perfect for organizing API versions (e.g., /api/v1/, /api/v2/) or feature modules.
Testing Your Routes
Test your API endpoints using curl:
GET Request
POST Request
Route Parameters
DELETE Request
curl http://localhost/api/test
Using Closures vs Named Functions
FastRoute supports both closures and named functions as handlers:
Closure Handler
Named Function Handler
Class Method Handler
$r -> get ( '/api/status' , function () {
echo json_encode ([ "status" => "online" ]);
});
Closures are convenient for simple routes, while named functions or class methods are better for complex logic that you want to test or reuse.
Common Patterns
Dynamic Route Parameters
Use custom regex patterns to validate route parameters:
// Numeric ID only
$r -> get ( '/user/{id:\d+}' , 'get_user' );
// Alphanumeric slug
$r -> get ( '/post/{slug:[a-z0-9-]+}' , 'get_post' );
// UUID pattern
$r -> get ( '/resource/{uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}}' , 'get_resource' );
Handling JSON Requests
function create_item ( $vars ) {
// Parse JSON body
$data = json_decode ( file_get_contents ( 'php://input' ), true );
// Validate and process
if ( ! $data ) {
header ( 'HTTP/1.1 400 Bad Request' );
echo json_encode ([ "error" => "Invalid JSON" ]);
return ;
}
// Handle the data
echo json_encode ([ "success" => true , "data" => $data ]);
}
What’s Next?
You now have a working FastRoute application! Here are some next steps:
Add authentication middleware
Implement error handling
Connect to a database
Build a complete REST API
Add request validation
Remember to add proper error handling and security measures before deploying to production.