Shortly after releasing version 0.4.1 of my Laravel Route Annotations package, I found an interesting bug with registering Resource routing and adding additional routes to the same controller.
So I’ve been working some fixes for that which are now in version 0.5.0 😃
The Bug
When registering Resource routing. Laravel allows a nice shortcut for doing this, which means you don’t have to register all the CRUD (Create, Read, Update, Delete/Destroy) actions yourself.
Route::resource('photos', PhotoController::class);
If you want to register additonal routes they have to be defined first, for example:
Route::get('/photos/popular', [PhotoController::class, 'popular']);
Route::resource('photos', PhotoController::class);
Otherwise hitting photos/popular
would actually match the route for editing photo, photos/{photo}
.
This was the bug I introduced when adding support for Resource and API Resource routing. Because of how you define resource routing, they get registered when the destuctor (__descruct method) of the PendingResourceRegistration
is called, meaning they were getting registered before I was going to process them.
Now I won’t jump into how PendingResourceRegistration
works, but if you are interested you can follow how the classes relate and what methods are called relatively easier:
Route::resource
uses the Route Facade- This actually calls the
resource
method of theIlluminate\Routing\Router
class - A
Illuminate\Routing\PendingResourceRegistration
instance is returned, which at this point no Routes are registed. Kinda obvious given the name of the class.
What I learnt
Clearly I needed to make sure I knew and understood what I working with, i.e how Laravel handles its routing.
What Does the New Change Look Like
Now as I said before, this is how you currently do it in Laravel.
Route::get('/photos/popular', [PhotoController::class, 'popular']);
Route::resource('photos', PhotoController::class);
With the Route Annotation Package you can do it as follows:
Route::annotation(PhotoController::class);
And the controller would look like:
<?php
namespace App\Http\Controllers;
use SmashedEgg\LaravelRouteAnnotation\ResourceRoute;
use SmashedEgg\LaravelRouteAnnotation\Route;
#[ResourceRoute(name: 'photos')]
class PhotoController extends Controller
{
#[Route(uri: '/photos/popular')]
public function popular()
{
}
public function index()
{
}
public function create()
{
}
public function store()
{
}
public function show()
{
}
}
Summary
That is the latest change in version 0.5.0. Thanks to everyone thats currently using the package and to those that have provided feedback.
Hoping the next release will be version 1.0!
Any feedback and suggestions is very much welcome and appreciated.