Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Auto Routes Laravel Package

izniburak/laravel-auto-routes

Automatically generates Laravel routes from controller method names, letting you skip hand-written entries in routes/web.php. Supports middleware, prefixes, namespaces, and route caching, making it handy for convention-based CRUD apps and APIs.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish config:

composer require izniburak/laravel-auto-routes
php artisan vendor:publish --provider="Izniburak\LaravelAutoRoutes\AutoRouteServiceProvider"

This drops config/auto-routes.php into your app. Before touching controllers, open that file first — it is the single source of truth for the package. The keys you care about are the enable toggle, the controller scan path(s), the root namespace, and the default middleware stack. Set enable => true, point paths at app/Http/Controllers, and set middleware to ['web'] (or ['api']) so generated routes behave like normal web routes.

First use case — a controller that registers itself. The typical first experiment is a throw-away HomeController:

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use Izniburak\LaravelAutoRoutes\Attributes\Route;

class HomeController extends Controller
{
    #[Route('/')]
    public function index()
    {
        return view('welcome');
    }

    #[Route('/about', methods: ['get'])]
    public function about()
    {
        return view('about');
    }
}

Then run php artisan route:list and confirm the routes appear with the framework's normal formatting. Once you see them there, you know discovery, namespace resolution, and middleware wiring are all working. Anything that goes wrong later will almost always be a variant of one of those three.

If the attribute flavor does not compile on your PHP/Laravel version, the package also ships a method-name-convention mode (getIndex, postStore, putUpdate, deleteDestroy) that maps HTTP verbs onto method prefixes — check the config file for the switch that turns that on.

Implementation Patterns

Attribute-based routing for CRUD resources. The cleanest day-to-day pattern is to group the seven REST methods in one controller and annotate each:

#[Route('/posts', methods: ['get'], name: 'posts.index')]
public function index() {}

#[Route('/posts/{post}', methods: ['get'], name: 'posts.show')]
public function show(Post $post) {}

#[Route('/posts', methods: ['post'], name: 'posts.store')]
public function store(Request $request) {}

#[Route('/posts/{post}', methods: ['put', 'patch'], name: 'posts.update')]
public function update(Request $request, Post $post) {}

Route model binding and named routes work exactly as they would in routes/web.php, which means route('posts.show', $post) in Blade keeps working. This is the pattern most teams settle into because it keeps the URL next to the method that serves it.

Route group attributes on the class. Apply a prefix and middleware once on the controller instead of repeating it per method — useful for admin or API surfaces:

#[RouteGroup('/admin/posts', middleware: ['auth', 'admin'])]
class AdminPostController extends Controller
{
    #[Route('/', methods: ['get'])]
    public function index() {}
}

This is where the package earns its keep. You get an api.php-style grouping without a separate route file, and the controller stays the only thing you have to open when a URL changes.

Keep it in a dedicated directory. Point the config paths at app/Http/Controllers/Auto (or an Api subfolder) instead of the whole controllers tree. The convention then becomes "anything here is auto-routed, anything outside is manual," which avoids the mental overhead of guessing which controllers are discovered and which are hand-registered. Manual routes/web.php routes and auto routes coexist fine — Laravel just loads both.

Combine with middleware aliases. Since middleware runs through the standard HTTP kernel, you can use your named aliases ('auth', 'throttle:60,1', 'verified') in the attribute the same way as in a route file. For a large app, split discovery into multiple groups (web / api / admin) by using multiple namespace entries in the config, each with its own middleware, rather than one giant scan.

Use it as the "quick internal tool" layer. Where this package actually shines is small admin panels, dashboards, or internal tools where you write ten thin controllers and don't want ten route-file entries keeping them in sync. For public-facing, stable APIs, the conventional routes/api.php remains easier to review and diff.

Debug via php artisan route:list --columns=method,uri,name,middleware. That one command is the whole debugging workflow — if the route is missing, the attribute name or namespace is wrong; if middleware is wrong, the config middleware or group attribute is off; if the method is wrong, the methods: array is off.

Gotchas and Tips

Discovery is boot-time, so caching matters. The package registers routes from reflection/scanning during the service provider's boot. That means php artisan route:cache should be tested explicitly in your CI — if the cache and the scan disagree, you get routes that work locally and 404 in production. Run route:clear && route:cache && route:list after every deploy step that touches controllers.

New controllers require a fresh boot. In Octane or long-running workers, adding a new controller file will not register until the worker restarts. In FPM this is invisible; anywhere else, plan for php artisan optimize or an Octane reload in your deploy script.

Namespace/path mismatches are the number one failure mode. App\Http\Controllers in the config must line up with the actual PSR-4 namespace and the PSR-4 mapping in composer.json. If a controller lives in a subfolder, the attribute path does not pick up the folder — only the class namespace does. When a route is missing, check composer dump-autoload first, then the namespace key, then the paths key, in that order.

Route ordering is not obvious. Attributes are discovered in filesystem order, not alphabetically, and wildcard routes (/posts/{post}) can shadow literal routes (/posts/create) depending on the order they land. If create starts hitting show, the fix is to declare a literal route in routes/web.php (manual routes win because they load in the standard order) or constrain the wildcard with where/->whereNumber('post').

The attribute syntax is PHP 8+ only. On PHP 7.x you are stuck with the method-name convention, which is more restrictive (you can't express patch, multiple middleware per route, or named routes cleanly). Check composer.json's PHP constraint before you commit to a pattern.

Middleware attribute is opt-in per route, not per action. Class-level RouteGroup middleware stacks before method-level middleware. If you find auth running twice, it's because both the config's default middleware array and the group attribute include it — pick one place to own it.

Config toggle is global. There is no per-controller "disable auto-routing" flag — only the whole package. If you want one controller excluded, move it out of the configured paths directory. This is why a dedicated directory is worth the setup cost.

Route names can collide. If two controllers both declare #[Route(..., name: 'index')], Laravel silently keeps the last one; route('index') then generates the wrong URL with no error. Enforce a prefix (name: 'admin.posts.index') in code review.

Be aware of the maintenance profile. 234 stars and a last release in August 2024 puts this on the "works but not heavily battle-tested" end of the ecosystem — the 1.65 score reflects that. That's not a blocker for an internal tool, but for anything long-lived, wrap the package behind your own tiny AutoRouteServiceProvider that calls the package's registration, so swapping it for spatie/laravel-route-attributes (further down the same path, but more actively maintained) is a one-file change instead of a controller-wide rewrite.

Extension point. The service provider exposes the discovery loop, so if you need custom logic (skip controllers with a marker interface, add a default prefix), subclass the provider and override the scan step rather than editing published config repeatedly. Published config is safe to edit; the vendor provider is not — fork or override.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager