Routing

Basic Routing

The most basic Kiaan routes accept a URI and a closure, providing a very simple and expressive method of defining routes and behavior without complicated routing configuration files:

use Kiaan\Route;
 
Route::get('/greeting', function () {
    return 'Hello World';
});

For most applications, you will begin by defining routes in your resources/routes/web.php file.

The routes defined in resources/routes/web.php may be accessed by entering the defined route's URL in your browser. For example, you may access the following route by navigating to http://localhost.com/kiaan/user in your browser:

Route::get('/user', "UserController");

Routes defined in the resources/routes/api.php file are nested within a route group.

Within this group, the /api URI prefix is automatically applied so you do not need to manually apply it to every route in the file.

Available Router Methods

The router allows you to register routes that respond to any HTTP verb:

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
Route::copy($uri, $callback);
Route::lock($uri, $callback);
Route::unlock($uri, $callback);
Route::propfind($uri, $callback);

Sometimes you may need to register a route that responds to multiple HTTP verbs.

You may do so using the methods method. Or, you may even register a route that responds to all HTTP verbs using the any method:

Route::methods(['get', 'post'], '/', function () {
    //
});
 
Route::any('/', function () {
    //
});

When defining multiple routes that share the same URI, routes using the get, post, put, patch, delete, copy, lock, unlock, propfind and options methods should be defined before routes using the any, methods.

This ensures the incoming request is matched with the correct route.

CRUD routes

Because of this common use case, Laravel resource routing assigns the typical create, read, update, and delete CRUD routes to a controller with a single line of code.

Route::crud("/user", "UsersController");
// Or
Route::crud("/user", UsersController::class);

This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions.

You may even register many resource controllers at once by passing an array to the cruds method:

Route::cruds([
    'photos' => "PhotoController",
    'posts' => "PostController",
]);

Actions Handled By CRUD Controller

API CRUD routes

Can use CRUD for api with apiCrud method.

Route::apiCrud("/user", "Api/UsersController");
// Or
Route::apiCrud("/user", UsersController::class);

You may even register many resource controllers at once by passing an array to the apiCruds method:

Route::apiCruds([
    'photos' => "Api/PhotoController",
    'posts' => "Api/PostController",
]);

Actions Handled By API CRUD Controller

CSRF protection

Remember, any HTML forms pointing to POST, PUT, PATCH, Copy, LOCK, UNLOCK, PROPFIND or DELETE routes that are defined in the web routes file should include a _csrf field. Otherwise, the request will be rejected.

<form method="POST" action="/profile">
    @csrf
    ...
</form>

Form Method

Remember, any HTML forms pointing to POST, PUT, PATCH, Copy, LOCK, UNLOCK, PROPFIND or DELETE routes that are defined in the web routes file should include a _method field.

<form method="POST" action="/profile">
    @csrf
    @method('put')
    ...
</form>

Redirect Routes

If you are defining a route that redirects to another URI, you may use the Route::redirect method.

This method provides a convenient shortcut so that you do not have to define a full route or controller for performing a simple redirect:

Route::redirect('/here', '/there');

Helpers

You can add custom functions to implement custom action.

The first parameter takes the name of the function and the second parameter is the function callback.

 Route::xCommand("Hello", function($name){
 return "Hello $name";
 });

View Routes

If your route only needs to return a view, you may use the Route::page(). Like the redirect method, this method provides a simple shortcut so that you do not have to define a full route or controller. The view method accepts a URI as its first argument and a view name as its second argument. In addition, you may provide an array of data to pass to the view as an optional third argument:

Route::page("/welcome", "welcome");

Route::page("/welcome", "welcome", ["name"=>"Hassan"]);

Route::page("/welcome", "welcome", ["name"=>"Hassan"] , "get", ["Middleware"=>"HelloWorld"]);

The Route List

The Route:list() an easily provide an overview of all of the routes that are defined by your application:

Route::list();

Route Parameters

Required Parameters

Sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user's ID from the URL.

You may do so by defining route parameters:

Route::get('/user/{id}', function ($id) {
    return 'User '.$id;
});

You may define as many route parameters as required by your route:

Route::get('/posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

Route parameters are always encased within {} braces and should consist of alphabetic characters. Underscores (_) are also acceptable within route parameter names. Route parameters are injected into route callbacks / controllers based on their order - the names of the route callback / controller arguments do not matter.

Optional Parameters

Occasionally you may need to specify a route parameter that may not always be present in the URI. You may do so by placing the parameter name between [ ].

Make sure to give the route's corresponding variable a default value:

Route::get("/user/[id]/", function($id=null){
//
});

Regular Expression Constraints

You may constrain the format of your route parameters on a route instance.

Accepts the name of the parameter and a regular expression defining how the parameter should be constrained:

Route::get('/user/{name:[0-9]+}', function ($name) {
    //
});

Route::get('/user/{name:[A-Za-z]+}', function ($name) {
    //    
});

Route::get('/user/{name:[a-z]+}', function ($name) {
//
});

Route::get('/user/{name:[A-Z]+}', function ($name) {
    //
});

For convenience, some commonly used regular expression patterns have helper methods that allow you to quickly add pattern constraints to your routes:

Route::get('/user/{name:alpha}', function ($name) {
    //
});

Route::get('/user/{name:alphaNumeric}', function ($name) {
    //
});

Route::get('/user/{name:numeric}', function ($name) {
    //
});

If the incoming request does not match the route pattern constraints, a 404 HTTP response will be returned.

Global Constraints

If you would like a route parameter to always be constrained by a given regular expression, you may use the pattern method.

Route::pattern('id', '[0-9]+');

Once the pattern has been defined, it is automatically applied to all routes using that parameter name:

Route::get('/user/{id}', function ($id) {
    // Only executed if {id} is numeric...
});

Named Routes

Named routes allow the convenient generation of URLs or redirects for specific routes. You may specify a name for a route by name onto the route definition:

Route::get('/user/profile', function () {
    //
}, ["name"=>"profile"]);

// Or


Route::get('/users', function () {
    //
})->name("users");

You may also specify route names for controller actions:

Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
 )->name("profile");

Route names should always be unique.

Generating URLs To Named Routes

Once you have assigned a name to a given route, you may use the route's name when generating URLs or redirects via Kiaan's route and goRoute helper functions:

// Generating URLs...
$url = Route::url('welcome');
// Or
$url = route('profile', ["id"=>1]);
 
// Generating Redirects...
Route::go('welcome');
// Or
return goRoute('profile', ["id"=>1]);

If the named route defines parameters, you may pass the parameters as the second argument to the route function.

The given parameters will automatically be inserted into the generated URL in their correct positions:

Route::get('/user/{id}/profile', function ($id) {
    //
})->name("profile");
 
$url = route('profile', ['id' => 1]);

Route Groups

Route groups allow you to share route attributes, such as middleware, across a large number of routes without needing to define those attributes on each individual route.

Nested groups attempt to intelligently "merge" attributes with their parent group.

Middleware and where conditions are merged while names and prefixes are appended.

Namespace delimiters and slashes in URI prefixes are automatically added where appropriate.

Middleware

To assign middleware to all routes within a group, you may use the middleware method. Middleware are executed in the order they are listed in the array:

Route::group(function () {
    Route::get('/', function () {
        // Welcome middleware...
    })->middleware("Welcome");
 
    Route::get('/user/profile', function () {
        // Uses first & second middleware...
    });
}, [
    "middleware" => ["first", "second"]
]);

Route::get('/hello', function () {
    // 
})->middleware("hello:handel, var1, var2");

// Or
Route::get('/hi', function () {
    // 
})->middleware(Hi::class . ":handel, var1, var2");

Controllers

Second parameter can define as controller.

Route::get("/a", WelcomeController::class);
Route::get("/b", [WelcomeController::class, "index"]);
// Or
Route::get("/c", "WelcomeController");
Route::get("/d", "WelcomeController, index");
Route::get("/e", ["WelcomeController", "index"]);
// Or
Route::get("/f", "UsersController,index", ["controller"=>"Users"]);
Route::get("/g", "UsersController,index")->controller("Users");

Or callback function

Route::get('/user/{name}', function ($name) {
    //
});

If a group of routes all utilize the same controller, you may use the controller to define the common controller for all of the routes within the group.

Then, when defining the routes, you only need to provide the controller method that they invoke:

Route::group(function() {
    Route::get("/user", ",index");
    Route::get("/profile", ",show");

}, ["controller"=>"Users/UsersController"]);

Route Prefixes & suffix

The prefix & suffix may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:

Route::group(function () {
    Route::get('/users', function () {
        // Matches The "/admin/users" URL
    });
}, [
    "prefix" => "admin"
]);

Route::group(function () {
    Route::get('/users', function () {
        // Matches The "/users/admin" URL
    });
})->suffix("admin");

Route Name Prefixes

The namemay be used to prefix each route name in the group with a given string. For example, you may want to prefix all of the grouped route's names with admin.

The given string is prefixed to the route name exactly as it is specified, so we will be sure to provide the trailing . character in the prefix:

Route::group(function () {
    Route::get('/users', function () {
        // Route assigned name "admin.users"...
    }, ["name" => "users"]);
})->name(admin.");

Fallback Routes

Using the Route::fallback method, you may define a route that will be executed when no other route matches the incoming request.

Typically, unhandled requests will automatically render a "404" page via your application's exception handler.

However, since you would typically define the fallback route within your resources/routes/web.php file, all middleware in the web middleware group will apply to the route.

You are free to add additional middleware to this route as needed:

Route::fallback(function () {
    //
});

// OR
Route::fallback(WelcomeController::class);
// OR
Route::fallback("WelcomeController");
// OR
Route::fallback("WelcomeController, index");
// OR
Route::fallback(["WelcomeController", "index"]);

Form Method Spoofing

HTML forms do not support PUT, PATCH, or DELETE actions.

So, when defining PUT, PATCH, or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form. The value sent with the _method field will be used as the HTTP request method:

<form action="/example" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_csrf" value="{{ csrfToken() }}">
</form>

Accessing The Current Route

You may use the current, on methods on the Route facade to access information about the route handling the incoming request:

Route::current();

Last updated