Skip to content

Conversation

AmirHkrg
Copy link

@AmirHkrg AmirHkrg commented Jul 26, 2025

This pull request introduces the foundational support for attribute-based routing in Laravel. It provides a clean, modern, and developer-friendly way to declare routes directly on controller methods.

Discussions

Motivation

As PHP continues to evolve, attributes have become a powerful tool for declarative programming. Many modern frameworks have adopted them for routing, which helps co-locate route definitions with their corresponding logic, improving clarity and developer ergonomics. This PR aims to bring this same modern convenience to Laravel, embracing modern PHP capabilities more deeply.

Crucially, this system is designed to work in conjunction with the traditional file-based routing system, not as a replacement. Developers can use both methods side-by-side in the same application, giving them more flexibility in how they organize their projects.

Proposed Solution

The feature is opt-in and enabled via a new fluent method, withAttributeRouting(), in bootstrap/app.php.

  1. Enabling the Feature
    Developers can easily specify which directories should be scanned for web and api route groups. If called with no arguments, it uses a sensible default.
// in bootstrap/app.php

return Application::configure()
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
    )
    // Example 1: Enable with a sensible default
    // (Scans app/Http/Controllers for the 'web' group)
    ->withAttributeRouting()

    // Example 2: Or, provide explicit configuration
    // ->withAttributeRouting(
    //     web: app_path('Http/Web'),
    //     api: app_path('Http/Api')
    // )
    ->...
  1. Defining Routes
    Controllers are marked for discovery by implementing the AttributeRouteController interface. Routes and groups are then defined with simple attributes:
<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Attributes\{Get, Group, Post};
use Illuminate\Routing\Attributes\AttributeRouteController;

#[Group(prefix: 'users', name: 'users.', middleware: 'auth')]
class UserController extends Controller implements AttributeRouteController
{
    #[Get('/', name: 'index')]
    public function index()
    {
        // Route: GET /users
        // Name: users.index
    }

    #[Post('/', name: 'store')]
    public function store()
    {
        // Route: POST /users
        // Name: users.store
    }
}

Performance Considerations

The performance impact of this feature has been carefully considered. In local development, a negligible overhead of a few milliseconds is introduced by the file scanning process. However, in production, once routes are cached using php artisan route:cache, there is zero performance impact. The only change is a simpler and more enjoyable development workflow.

This is an MVP

This initial pull request implements the Minimum Viable Product (MVP) for this feature. The goal is to first agree on the fundamental architecture and API.

I have already locally developed and tested more advanced features that can be added in subsequent PRs upon approval of this core concept. These future possibilities include:

  • #[Resource] and #[ApiResource] attributes for full RESTful controller support.
  • Advanced #[Group] features like only and except for targeting specific methods.
  • scopeBindings support for both resources and groups.
  • An implicit discovery mode to reduce boilerplate.
  • Enhancements to Artisan commands (route:list and make:controller).

Currently, there are third-party packages available for this purpose, but it’s possible to offer such a feature — which already exists in most modern frameworks — directly within Laravel itself. This would allow for greater compatibility, a more controlled structure, and higher flexibility. For example, editing route commands and similar functionalities that cannot be modified in third-party packages.

It could also be developed in a much more advanced way with newer and more complete ideas, aligned with Laravel’s philosophy.

Of course, I understand that adding more logic and code will make development and maintenance more challenging. However, I am capable of carrying out the full development, and Laravel’s large and active community will also help along the way.

Next Steps & Collaboration

I am fully committed to seeing this feature through to completion. If this initial proposal is accepted by the team and the community, I am ready to collaborate on any necessary changes and submit the subsequent PRs to build out the full feature set.

@AmirHkrg AmirHkrg marked this pull request as draft July 26, 2025 02:06
@AmirHkrg AmirHkrg marked this pull request as ready for review July 26, 2025 02:13
@AmirHkrg AmirHkrg marked this pull request as draft July 26, 2025 02:27
@macropay-solutions
Copy link

The feature is opt-in and enabled via a new fluent method, withAttributeRouting(), in bootstrap/app.php.

Thank you for not making it a default. If this gets merged, symfony lovers will clap their hands like a circus seal.

@antonkomarev
Copy link
Contributor

I have a project, where we have more than one directory of web routes and many API routes directories, some of them are located outside of App namespace. I think this should be more flexible.

@AmirHkrg
Copy link
Author

AmirHkrg commented Sep 1, 2025

I have a project, where we have more than one directory of web routes and many API routes directories, some of them are located outside of App namespace. I think this should be more flexible.

Hi @antonkomarev

You can easily specify a list of folders to scan,
and this feature currently exists in this pull request.

->withAttributeRouting(
    web: [
        base_path('src/Invoicing/UI/Web'),
        base_path('src/Customers/UI/Web'),
    ],
    api: [
        base_path('src/Invoicing/UI/Api'),
        base_path('src/Customers/UI/Api'),
    ]
)

Of course, this is just an MVP version; if its addition is approved, other features will be added as well.

@crynobone crynobone added the needs work Not quite ready for primetime label Sep 11, 2025
@crynobone
Copy link
Member

Test are failling

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs work Not quite ready for primetime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants