Reputation: 2882
I'm trying to extend the Laravel 5.6 router class to add some handy methods to register routes.
I have created a class that extends the Illuminate\Routing\Router
class like this:
Namespace App\Overrides;
use Illuminate\Routing\Router as LaravelRouter;
class Router extends LaravelRouter
{
public function apiReadResource($name, $controller, array $options = [])
{
$this->resource($name, $controller, array_merge([
'only' => ['index', 'show'],
], $options));
}
public function apiWriteResource($name, $controller, array $options = [])
{
$this->resource($name, $controller, array_merge([
'except' => ['index', 'show', 'edit', 'create', 'destroy'],
], $options));
}
public function apiRelationshipResources($name, $controller, array $relationships, array $options = [])
{
foreach($relationships as $relationship)
{
$this->get(
$name.'/{id}/'.$relationship,
[
'uses' => $controller . '@' . $relationship,
'as' => $name . '.' . $relationship,
]
);
}
}
}
I have registered my extended class like this in the default App\Providers\RouteServiceProvider
:
namespace App\Providers;
use Illuminate\Routing\Router;
use App\Overrides\Router as APIRouter;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
public function register()
{
$this->app->singleton('router', function ($app) {
return new APIRouter($app['events'], $app);
});
}
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
[more code...]
}
In the routes file I call my own custom methods like this: Route::apiWriteResource('users', 'UserController');
or like this Route::apiRelationshipResources('users', 'UserController', ['reviews']);
All routes are registered and show up correctly in php artisan route:list
, but none of the routes actually work. They all gives the standard 404 page.
What am I doing wrong? What have I missed?
Upvotes: 4
Views: 1060
Reputation: 19372
Based on documentation from here, here, here and checking in Router.php I came to idea to write an answer.
Try following steps:
1) Create Routing folder inside of app folder
Create a macros:
2) app\Routing\ApiReadResource.php with such content:
<?php
namespace App\Routing
use Illuminate\Routing\Router;
class ApiReadResource
{
public static function register()
{
if (!Router::hasMacro('apiReadResource')) {
Router::macro('apiReadResource', function ($name, $controller, $options = []) {
Router::resource(
$name,
$controller,
array_merge(['only' => ['index', 'show']], $options)
);
});
}
}
}
3) app\Routing\ApiWriteResource.php with such content:
<?php
namespace App\Routing
use Illuminate\Routing\Router;
class ApiWriteResource
{
public static function register()
{
if (!Router::hasMacro('apiWriteResource')) {
Router::macro('apiWriteResource', function ($name, $controller, $options = []) {
Router::resource(
$name,
$controller,
array_merge(['except' => ['index', 'show', 'edit', 'create', 'destroy']], $options)
);
});
}
}
}
4) app\Routing\ApiRelationshipResources.php with such content:
<?php
namespace App\Routing
use Illuminate\Routing\Router;
class ApiRelationshipResources
{
public static function register()
{
if (!Router::hasMacro('apiRelationshipResources')) {
Router::macro('apiRelationshipResources', function ($name, $controller, array $relationships, $options = []) {
foreach($relationships AS $relationship) {
Router::get(
$name.'/{id}/'.$relationship,
array_merge($options, [
'uses' => $controller . '@' . $relationship,
'as' => $name . '.' . $relationship,
])
);
}
});
}
}
}
5) Register them inside AppServiceProvider:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
\App\Routing\ApiReadResource::register();
\App\Routing\ApiWriteResource::register();
\App\Routing\ApiRelationshipResources::register();
}
}
Upvotes: 2