Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

pedroborges's avatar

Route annotation in Laravel 5

Laravel 5 now includes route annotation. Which means now you can have a controller like this:

<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;

/**
 * @Resource("foobar/photos", only={"index", "update"}, names={"index": "index.name"})
 * @Controller(domain="{id}.account.com")
 * @Before("auth")
 * @Before("csrf", on={"post", "put", "delete"})
 * @Where({"id": "regex"})
 */
class BasicController extends Controller {

 /**
  * @Before("inline")
  * @return Response
  */
 public function index() {}

 /**
  * @Before("inline")
  * @After("inline")
  * @return Response
  */
 public function update($id) {}

 /**
  * @Put("/more/{id}", after="log")
  */
 public function doMore($id) {}

}

Then you have to run php artisan route:scan and Laravel will cache all annotated routes in storage/framework/routes.scanned.php

What do you guys think of this feature?

0 likes
152 replies
jacob's avatar

I think it's a pretty cool feature, but I'm probably still going to register the routes without annotation. I like being able to look at a single routes file and seeing exactly what is routed.

So personally, not a huge fan. But I know some people are gonna love it.

2 likes
pedroborges's avatar

@jacob It's indeed a cool feature. Taylor also made very flexible so people can use it along with the routes file. Routes defined in annotation are also listed when you run the route:list.

xingfucoder's avatar

Correct me if I'm wrong, but this way to work with Routes could not be used to specify some Events too?

As following sample:

/*
* @UserWasAdded Listeners={'SendNotification', 'UpdateStats'}
*/

I think the annotation could give more capabilities for another laravel fields.

JeffreyWay's avatar

Yeah - you very well might see an event scanner, too. We'll have to wait and see.

xingfucoder's avatar

Yes, we will waiting all those Laravel features as Christmas Gifts :-)

Oddman's avatar

The great thing about this is that it follows a configuration-as-annotation arrangement for Laravel 5. I do not particularly think doing this for events makes sense, as events tend to be tied to your business domain, not your http layer.

I'm super happy about this, I hate routes.php hehe

xingfucoder's avatar

Hi @Oddman, was referring to events management in the annotations associated with another classes, not HTTP. For example Domain Events associated with Entity changes. If you see my annotation refers to UserWasAdded (where User may be the Model or Entity)

Hope I explain it better.

1 like
JeffreyWay's avatar

If you had a event listener that has the @hears("foo") annotation, then Laravel could generate a cached event listeners file automatically.

1 like
xingfucoder's avatar

Yeah @JeffreyWay, what about use with Dependency Injection?

/*
* @param $interfaceName (bind{\Namespace\To\Your\Interface', 'ImplementedClass'})
*/

Then you could bind differente implementations of the same Interface in some methods, not only the same implementation class.

Correct me if I'm wrong.

Note. I didn't work before with annotation and maybe I put in wrong way it. Sorry :(

1 like
rspahni's avatar

Back to the OP for a sec: It's probably for my lack of knowing/grasping latest architectural concepts but it strikes me as pretty counter-intuitive to use doc blocks for elementary app logic, whether domain or http related. PhpStorm seemingly of the same opinion, according to its dull uniform grey in the screenshots for such important matters... ;-) Or, vis-à-vis Laravel's selling proposition - this, to me, is neither expressive nor elegant and before seeing @JeffreyWay's eventual video on the subject, I fail to see yet a scenario where this approach will allow me to do things I could not make happen with good old routes.php plus filters registered in the constructor [which I learned about here at Laracasts]. Taylor's universal approach of giving devs a choice all the more appreciated but honestly, at the end of the day, having x different options for doing one elementary thing, to 99.9% the same effect, might not help Laravel's adoption and accessibility.

8 likes
keevitaja's avatar

Lol, i was just wandering why the hell do i see a comment like this:

 /**
  * @Get("/", as="home")
  */
 public function index()
 {
  return view('hello');
 }

But i think i will not start using them, can be too confusing to hunt the routes down after some time away from the project.

xingfucoder's avatar

Yes @keevitaja, I think actually will be some confusing and dinamic. I would wait for more stable version. I suppose that the "as" is the route name, but I think we need to wait for more announcements.

JeffreyWay's avatar

It won't be confusing at all. There will be a cached routes file that you can refer to, and you can also always run php artisan route:list.

2 likes
keevitaja's avatar

How would you debug this? Check cached route file, then go to controller? What about stupid typos in this comment-style-routing? It will be a real pain in the ass!

1 like
JeffreyWay's avatar

No it won't. You'll debug it in the exact same way, as if you were manually writing them in your routes.php file.

2 likes
xingfucoder's avatar

I refer confusing because we haven't official characteristic about its use, and it is changing some times right now.

I think when we will be using it, we will not return from annotations :)

RayRutjes's avatar

I personally have had some bad experiences with annotations when used to code with Symfony 2. I had annotations for Validation, Routing, Orm stuff etc, I really found it became a mess.

But who knows, maybe this time I'll adopt them if it makes sense.

1 like
xingfucoder's avatar

I think that one probably specific use that I would apply it may be when you use Resources routes:

$router->resource('users', 'UsersControllers');

If you after define all resource routes because you need to asign a name to each route, the annotation may reduce the named route definitions.

Note. Watching the last lesson is same feature about renaming route names :) great lesson @JeffreyWay many thanks.

pedroborges's avatar

Taylor suggested to use a watcher to rescan routes when any file inside app/HTTP/Controllers changes. I would also suggest to recreate a routes file with that watcher for better reference, like: php artisan route:list > app/HTTP/routes.txt.

Is it easy to run a command like that with Gulp?

JeffreyWay's avatar

@pedrobor_es About dumping the routes with each change, Laravel will already create a scanned routes file that you can refer to. So that won't be necessary.

About the Gulp task: yes, that's a cinch.

var gulp = require('gulp');
var shell = require('gulp-shell');

gulp.task('scan-routes', function() {
    gulp.src('').pipe(shell('php artisan route:scan', {ignoreErrors: true}));
});
1 like
acasar's avatar

@rspahni If you look at the Taylor's commit message, he said that all this functionality will be extracted to a legacy package for 4.* compatibility. So if you don't wish to refactor, your best bet is to wait for the package.

nWidart's avatar

It seems like the route:scan command doesn't check for routes everywhere? I have routes setup in Modules, for instance Modules/Session/Http/routes.php but those aren't scanned.

Just as the filters aren't scanned either. I have

/**
 * @Before("guest", on={"getLogin", "getRegister"})
 */
class AuthController
{

But it isn't noticing it.

acasar's avatar

@nWidart it only scans App/Http/Controllers by default. To override that, you need to call it like this:

php artisan routes:scan --namespace="your-controller-namespace" --path="your-controller-path"

Default path is Http/Controllers, so only provide it if yours is different.

1 like
alfrednutile's avatar

Is it common in other languages to use annotations as code? It still seems to me right now to take away from the readability of things.

2 likes
MThomas's avatar

I think that I bumped into a small 'bug' or I am missing something (eg. to define the order of the routes). I created the following annotations in a controller:

/**
 * @Resource("projects", only={"index", "create", "store"})
 * @Before("csrf", on={"post", "put", "delete"})
 */
class ProjectsController {

 /**
  * Display a listing of the all projects for the signedin user.
  *
  * @Before("auth")
  * @return Response
  */
 public function index()
 {
  //
 }

 /**
  * Show the form for creating a new project.
  *
  * @Before("auth")
  * @return Response
  */
 public function create()
 {
  //
 }

    /**
     * Store a newly created project.
     *
     * @Before("auth")
     * @param CreateProjectRequest $request
     * @return Response
     */
 public function store(CreateProjectRequest $request)
 {
  //
 }

 /**
  * Show the Project.
  *
  * @Before("auth")
  * @Get("projects/{project}", as="projects.show")
  */
    public function show($project)
    {
        //
    }
}

After running php artisan route:scan the routes are generated, however the order of the routes is not correct resulting in the fact that you can't access the route of the project show method:

$router->get('projects/{project}', ['uses' => 'Jonril\Http\Controllers\ProjectsController@show', 'domain' => NULL, 'as' => 'projects.show', 'before' => array (
), 'after' => array (
), 'where' => array (
)]);
$router->group(['before' => array (
  0 => 'auth',
), 'after' => array (
), 'prefix' => NULL, 'domain' => NULL, 'where' => array (
)], function($router) { $router->resource('projects', 'Jonril\\Http\\Controllers\\ProjectsController', ['only' => array (
  0 => 'index',
), 'names' => array (
)]); });
$router->group(['before' => array (
  0 => 'auth',
), 'after' => array (
), 'prefix' => NULL, 'domain' => NULL, 'where' => array (
)], function($router) { $router->resource('projects', 'Jonril\\Http\\Controllers\\ProjectsController', ['only' => array (
  0 => 'create',
), 'names' => array (
)]); });
$router->group(['before' => array (
  0 => 'csrf',
  1 => 'auth',
), 'after' => array (
), 'prefix' => NULL, 'domain' => NULL, 'where' => array (
)], function($router) { $router->resource('projects', 'Jonril\\Http\\Controllers\\ProjectsController', ['only' => array (
  0 => 'store',
), 'names' => array (
)]); });

The first route projects/{project} should not be at the top, due to this you can't access projects/create, this might be a bug, or something I'm missing (eg. how to define the order of the routes).

pmall's avatar

What is the benefits of annotations ? That's a genuine question, because I can't figure this out.

1 like
thepsion5's avatar

@alfrednutile Several other languages have annotations, but the important difference is that they're actually part of the language. Since annotations in PHP are in the comments, they're invisible to the PHP interpreter.

Personally, I don't like the idea of putting real application logic in comments. I'd much, much rather have the option of using an array configuration of some kind or even YAML.

4 likes
xingfucoder's avatar

Yeah @thepsion5, I think it is something as re-coding or coding within the comments, but I think the annotations in Laravel maybe brings great things.

Next

Please or to participate in this conversation.