In Drupal, routes are the entry point to backend logic.
Every page, controller, form, AJAX callback, or JSON response starts with a route. If custom modules define what behavior exists, routes define how a request reaches that behavior.
This article is the second article in the Level 2 – Backend Development series.
By the end of this article, you will understand:
- What a route is in Drupal
- How Drupal matches URLs to backend code
- Required and optional route keys
- How access control works at the routing level
- How routes fit into Drupal’s request lifecycle
1. What Is a Route (Simple Explanation)
A route tells Drupal:
- Which URL path to listen to
- What backend code should handle the request
- Who is allowed to access it
In plain terms:
A route is a map between a URL and backend logic.
Without routes, controllers, forms, and APIs cannot be reached.
2. Where Routes Are Defined
Routes are defined in a YAML file named:
MODULE_NAME.routing.yml
For our example module:
weeklydrupal_demo.routing.yml
Drupal discovers this file automatically when the module is enabled.
3. The Basic Route Structure
A minimal route definition looks like this:
weeklydrupal_demo.page:
path: '/weeklydrupal/demo'
defaults:
_controller: '\\Drupal\\weeklydrupal_demo\\Controller\\DemoController::page'
_title: 'WeeklyDrupal Demo'
requirements:
_permission: 'access content'
Each route has three core parts:
- Route name
- Path
- Handler and access rules
4. Route Name (Why It Matters)
weeklydrupal_demo.page:
This is the route machine name.
Rules:
- Must be unique across the site
- Usually starts with the module name
- Used internally by Drupal (links, redirects, access checks)
Example usage:
Url::fromRoute('weeklydrupal_demo.page')- Menu links and tasks reference route names
5. Path (The URL)
path: '/weeklydrupal/demo'
This is the URL users visit in the browser.
Guidelines:
- Paths should be human-readable
- Admin paths usually start with
/admin - Avoid hardcoding language prefixes
Drupal automatically handles language and base paths.
6. Defaults Section (What Runs)
defaults:
_controller: '\Drupal\weeklydrupal_demo\Controller\DemoController::page'
_title: 'WeeklyDrupal Demo'
_controller
- Points to a PHP class and method
- Uses the full namespace
- Format:
ClassName::methodName
Drupal will:
- Autoload the class
- Instantiate it
- Call the method
_title
- Sets the page title
- Can be a string or a callback
- Can be overridden dynamically later
7. Requirements Section (Access Control)
requirements:
_permission: 'access content'
This controls who can access the route.
Common requirement keys:
_permission– Check a permission string_role– Restrict by user role_custom_access– Custom access logic
If access fails, Drupal returns a 403 response automatically.
8. Route Access Is Checked Before Code Runs
Important concept:
If access fails, the controller is never executed.
This means:
- Security is enforced early
- Backend code stays clean
- Access logic does not belong in controllers
Drupal encourages declarative access control at the routing level.
9. Route Parameters (Dynamic URLs)
Routes can accept parameters:
weeklydrupal_demo.item:
path: '/weeklydrupal/demo/{id}'
defaults:
_controller: '\\Drupal\\weeklydrupal_demo\\Controller\\DemoController::item'
requirements:
id: '\\d+'
_permission: 'access content'
Drupal will:
- Extract
{id}from the URL - Pass it as a method argument
Example controller method:
public function item($id) {
return [
'#markup' => 'Item ID: ' . $id,
];
}
10. How Routes Fit Into the Request Lifecycle
Simplified flow:
- HTTP request arrives
- Drupal matches the URL to a route
- Access checks are evaluated
- Controller or form is executed
- Render array is returned
- Response is generated
Routes are the gateway into backend Drupal.
11. Common Mistakes to Avoid
- Hardcoding URLs instead of using route names
- Performing access checks inside controllers
- Mixing routing logic with business logic
- Forgetting to clear caches after changing routes
Routes are cached aggressively. Always rebuild cache after changes.
12. Learning by Building: Extending weeklydrupal_demo
In this topic, our module now supports:
- A static page route
- A parameterized route
- Permission-based access control
Future topics will reuse these routes for:
- Forms
- AJAX callbacks
- Admin pages
- API responses
13. Why Custom Routes Matter
If you understand routes:
- Controllers feel predictable
- Forms make sense
- Menu links become trivial
- Access control becomes consistent
Routes define the shape of your backend system.