Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Singleton routes for one-off resources in Laravel 9.x

December 7, 2022 ·

The way routes work in Laravel is that you define a route and then you define a controller action to handle the request.

Here are some examples of routes and their corresponding controller actions.

Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Route::post('/users', [UserController::class, 'store']);
Route::put('/users/{id}', [UserController::class, 'update']);
Route::delete('/users/{id}', [UserController::class, 'destroy']);

As you can tell, we define every route definition individually and then we define a controller action for each of them. This is fine as long as you have a lot of complex routes. Routes that involves, route model binnding, for instance.

But what if you have some resources that are one-off, meaning these resources won’t have multiple models?

For instance, a settings resource. You don’t have multiple settings. You have only one settings model of a user. So, in this case, the number of routes are pre-defined such as GET /settings, PUT /settings, GET /settings/edit, etc.

Laravel 9.x introduced a new feature called singleton routes which allows you to define a route for a one-off resource like settings in a single line. So, you don’t have to define a route for each of the actions explicitly.

Defining singleton routes

To define a singleton route, you can use the singleton helper on the Route facade. Here’s how you can define a singleton route for the settings resource.

Route::singleton('settings', SettingsController::class);

As you can see, you can define a singleton route by passing the resource name and the controller class name to the singleton helper.

Available singleton routes

The singleton helper will automatically register the following routes for you under the hood.

Route::get('/settings', [SettingsController::class, 'show']);
Route::put('/settings', [SettingsController::class, 'update']);
Route::get('/settings/edit', [SettingsController::class, 'edit']);

As you can see, the singleton method will automatically register the show, update, and edit routes for you.

Usually, the singleton routes won’t have creation and storage routes such as POST /settings and GET /settings/create. But if you want these, you can do so using the creatable method like so.

Route::singleton('settings', SettingsController::class)->creatable();

This will register the following routes for you.

Route::get('/settings', [SettingsController::class, 'show']);
Route::put('/settings', [SettingsController::class, 'update']);
Route::get('/settings/edit', [SettingsController::class, 'edit']);
Route::post('/settings', [SettingsController::class, 'store']);
Route::get('/settings/create', [SettingsController::class, 'create']);
Route::delete('/settings', [SettingsController::class, 'destroy']);

API Singleton Resources

If you want to define a singleton route for an API resource, you can use the apiSingleton helper on the Route facade. Here’s how you can define a singleton route for the settings resource.

Route::apiSingleton('settings', SettingsController::class);

This will register the following routes for you.

Route::get('/settings', [SettingsController::class, 'show']);
Route::put('/settings', [SettingsController::class, 'update']);
Learn the fundamentals of PHP 8 (including 8.1 and 8.2), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?