Skip to content

Routing

URL Structure

  1. Use kebab-case for URLs:

    text
    https://www.example.com/about-us
    https://www.example.com/user-profile
  2. Use camelCase for route parameters:

    php
    Route::get('users/{user}', ShowUserProfileController::class);

Route Definition

  1. Do not use Route::resource. Define routes explicitly to avoid unnecessary routes and simplify full text search by the project.

  2. Use array syntax for multiple middleware:

    php
    Route::get('about', AboutPageController::class)
        ->middleware(['cache:1day', 'auth']);

Route Naming

  1. Always name your routes (for HTML endpoints) and use the route() helper to generate URLs:

    php
    Route::get('about', ShowAboutPageController::class)->name('about.index');
    blade
    <a href="{{ route('about.index') }}">About</a>
  2. Use camelCase for route names:

    php
    Route::get('users/{user}', ShowUserProfileController::class)->name('userProfiles.show');

Using route()

There are few valid options on how to use route() helper for named routes:

php
// route: '/meetups/{meetupId}'
$meetup = \App\Modules\LocalGroup\Models\Meetup::query()->find($meetupId);

route('meetups.show', $meetup); // GOOD (RECOMMENDED) for routes with a single parameter
route('meetups.show', $meetupId); // GOOD for cases when you don’t have Meetup object but have an ID/key
route('meetups.show', [$meetup]); // BAD, please don’t use array syntax for a single param routes or use array keys
route('meetups.show', ['meetupId' => $meetup]); // GOOD (RECOMMENDED)
route('meetups.show', ['meetupId' => $meetupId]); // GOOD
route('meetups.show', ['id' => $meetup->id]); // ERROR: Missing required parameter "meetupId"

2+ required parameters:

php
// route: '/teams/{team}/members/{member}'
$member = \App\Models\Member::query()->with(['team'])->first();

route('teams.members.show', ['team' => $member->team, 'registration' => $member]); // GOOD, RECOMMENDED
route('teams.members.show', ['team' => $member->team_id, 'registration' => $member->id]); // GOOD, RECOMMENDED (when you don’t have a model object but have an id/key)
route('teams.members.show', [$member->team, $member]); // NOT RECOMMENDED
route('teams.members.show', ['member' => $member, 'team' => $member->team]); // BAD, params mixed up (but still working as expected)
// other options are not recommended also

API Design

  1. Use versioning for your API:

    php
    Route::prefix('api/v1')->group(function () {
        // API routes
    });
  2. Use plural nouns for resource endpoints:

    text
    GET /api/v1/articles
    POST /api/v1/articles
    GET /api/v1/articles/{article}
  3. Use nested resources for representing relationships:

    text
    GET /api/v1/articles/{article}/comments
    POST /api/v1/articles/{article}/comments
  4. Use query parameters for filtering, sorting, and pagination:

    text
    GET /api/v1/articles?sort=created_at&order=desc&page=2
  5. Use Laravel API Resources for transforming your models into JSON responses.

Controller + action notation

Tuple notation MUST be used to declare a route (when it’s possible):

php
// GOOD
Route::get('about', ShowAboutPageController::class); // invokable single action controller
Route::get('about', [AboutPageController::class, 'index']);

// BAD
Route::get('about', 'AboutPageController@index');

Route parameters

Route parameters SHOULD use camelCase.

php
Route::get('members/{memberId}', ShowMemberProfileController::class);

Verbs

All routes have an HTTP verb; that’s why we put the verb first when defining a route. It makes a group of routes very readable. Any other route options MUST come after it.

php
// GOOD: all http verbs come first
Route::get('/', HomeController::class)->name('home');

// BAD: http verbs not easily scannable
Route::name('home')->get('/', HomeController::class);