Newsletter
Newsletter

Routing on Laravel with Controller only

Scroll down
Samir Mammadhasanov
Samir Mammadhasanov
I`m
  • Residence:
    Azerbaijan
  • City:
    Baku
  • Age:
    24

June 25, 2022

14:32

Samir
Laravel routing on the new way with PHP8 Attributes

Attributes are a new feature in PHP 8.0 and are only available on > PHP 8.0. The goal of these attributes, also known as annotations in many other languages, is to add metadata to classes, methods, variables, and whatnot in a structured way.

Using Attributes on Routing will avoid additional routing file creation and improve the code’s readability. Also, the only requirement is PHP to do this feature and you don’t need to install any additional vendor package.

Let’s make a short comparison:

Before:

Default way routing

After:

Laravel routing on the new way with PHP8 Attributes

So let’s start to dive deep. How does this shortcut routing work?

First of all, I suggest you get familiar with the official attributes documentation of PHP.

If you are enough familiar with the main logic of the Attributes, we can continue to the next steps.

Let’s define our new attribute: Route

Create a new directory on the app folder with the name Attributes. Then you can create our new attribute file named Route.php:

Our custom Route attribute on Laravel

Then we need to update our route loading logic defined on RouteServiceProvider.php as below:

RouteServiceProvider.php

Final code:

<?php

namespace App\Providers;

use App\Attributes\Route as RouteAttribute;

class RouteServiceProvider extends ServiceProvider
{
    // ...

    public function boot()
    {
        $this->routes(function () {
            $rii = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(app_path('Http/Controllers')));

            foreach ($rii as $file) {
                // pass if the directory
                if ($file->isDir()) continue;

                // make our controller namespace
                $class = 'App\\Http\\Controllers\\' . $file->getBasename('.php');

                // create our virtual class
                $reflectionClass = new \ReflectionClass($class);

                // collect attributes of class if the invokable method is defined
                $classAttributes = collect($reflectionClass->getAttributes(RouteAttribute::class));

                // check if the class have attribute itself
                if ($classAttributes->isNotEmpty()) {
                    $arguments = collect($classAttributes->first()->getArguments());

                    // register our dynamic route
                    Route::match($arguments->get('method'), $arguments->get('path'), $class)
                        ->middleware($arguments->get('middlewares', []));
                }

                // check each method individually
                foreach ($reflectionClass->getMethods() as $method) {
                    // collect all attributes of the method
                    $methodAttributes = collect($method->getAttributes(RouteAttribute::class));

                    // pass if the method doesn't have any defined attributes
                    if ($methodAttributes->isEmpty()) continue;

                    // get arguments of our defined attribute
                    $arguments = collect($methodAttributes->first()->getArguments());

                    // register our dynamic route
                    Route::match($arguments->get('method'), $arguments->get('path'), $class . '@' . $method->getName())
                        ->middleware($arguments->get('middlewares', []));
                }
            }
        });
    }

    // ...
}

This routing configuration will loop and read all your defined controllers. If you add the Route attribute to any of your methods, defined arguments will be used to make our new route.

So you don’t need to add any Route to the routes folder.

Note: This functionality is only for one level Controllers file structure. If you are using nested folder structure you need to update boot method to load all files recursively.

If you want to use Single Action Controllers you need to add Route attribute to the class (not to method):

You can use path definition like default Routing definition. (adding required or optional parameters etc.)

Conclusion:

PHP is improving itself day by day and using this Attributes feature we can super boost our productivity on the code.

Posted in LaravelTags:
Write a comment

Write me a message
Write me a message

    * I promise the confidentiality of your personal information