Skip to content

abdelrhman-saeed/route

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Route

Route is a dynamic routing package for PHP applications, designed to simplify the creation of RESTful routes.


Installation

composer require abdelrhman-saeed/route

Prerequisites

  1. Entry Point File: Create an entry point file for your application (e.g., index.php).

  2. Server Configuration: Redirect all requests to this entry point file.

    Example using PHP's built-in server:

    php -S 127.0.0.1:8000
  3. Routes File: Create a separate file to define your routes (e.g., routes.php). You can store it anywhere in your project.


Usage Example

index.php:

<?php

use AbdelrhmanSaeed\Route\Api\Route;
use Symfony\Component\HttpFoundation\{Request, Response};

// Initialize the routing system
Route::setup('routes.php', Request::createFromGlobals(), new Response);

routes.php:

use AbdelrhmanSaeed\Route\Api\Route;
use App\Controllers\SomeKindOfController;

// Define routes with dynamic segments
Route::get('users/{user}/posts/{post}', function (int $user, int $post) {
    var_dump($user, $post);
});

// Use a controller to handle requests
Route::get('posts/{post}/comments/{comment}', [SomeKindOfController::class, 'someMethod']);

// Define routes with optional segments
Route::get('search/users/{user}/{filter?}', function (int $user, ?string $filter = null) {
    // Handle search logic
});

// Supported HTTP methods: ['get', 'post', 'put', 'patch', 'delete']
Route::post('test', function () {
    // Handle POST request
});

Route::put('test', function () {
    // Handle PUT request
});

// Define multiple methods for a single route
Route::match(['put', 'patch', 'delete'], 'test', function () {
    // Handle multiple request types
});

// Define a route for all HTTP methods
Route::any('test', function () {
    // Handle any HTTP method
});

Route Constraints

You can apply constraints to route segments to validate their format.

use AbdelrhmanSaeed\Route\Endpoints\Rest\Constraints\ConstraintsInterface;
use AbdelrhmanSaeed\Route\Api\Route;

// Define a constraint using regex
Route::get('users/{user}', fn (int $user) => var_dump($user))
     ->where('user', '[A-z]+');

// Use predefined constraints from ConstraintsInterface
Route::get('users/{user}/posts/{post}', function (int $user, string $post) {
    // Handle request
})
->where('user', ConstraintsInterface::NUM)
->where('post', ConstraintsInterface::ALPHANUM);

// Specify allowed values for a segment
Route::get('oauthcallback/{server}', function (string $server) {
    // Handle OAuth callback
})
->whereIn('server', ['facebook', 'google']);

Middleware

To add middleware to your routes, extend the AbdelrhmanSaeed\Route\Middleware class and implement the handle() method.

use AbdelrhmanSaeed\Route\Middleware;
use Symfony\Component\HttpFoundation\Request;

class RedirectIfAuthenticated extends Middleware
{
    public function handle(Request $request): void
    {
        // Perform checks before proceeding
        parent::handle($request);
    }
}

Assign middleware to a route:

Route::get('login', function () {
    // Login logic
})->setMiddlewares(RedirectIfAuthenticated::class);

Resource Routing

The Route::resource() method automatically generates RESTful routes for a given controller.

Route::resource('users', UserController::class);

This will generate:

  • GET /usersUserController::index()
  • POST /usersUserController::save()
  • GET /users/{user}UserController::show(mixed $user)
  • PUT, PATCH /users/{user}UserController::update(mixed $user)
  • DELETE /users/{user}UserController::delete(mixed $user)

If you set the api parameter to false, two additional routes will be generated:

  • GET /users/createUserController::create()
  • GET /users/{user}/editUserController::edit(mixed $user)
Route::resource('users', UserController::class, false);

Nested Resource Routing

You can define nested resource routes using dot notation:

Route::resource('users.posts', PostController::class);

This will generate routes like:

  • GET /users/{user}/postsPostController::index()
  • POST /users/{user}/postsPostController::save()
  • GET /users/{user}/posts/{post}PostController::show(mixed $post)

Apply constraints to nested routes:

Route::resource('users.posts', PostController::class)
     ->where('users', ConstraintsInterface::NUM)
     ->where('posts', ConstraintsInterface::ALPHANUM);

Shallow Nesting

Shallow nesting removes the parent ID from child routes when it's unnecessary.

Route::resource('users.posts', PostController::class, shallow: true);

This will generate routes like:

  • GET /users/postsPostController::index()
  • POST /users/postsPostController::save()
  • GET /users/posts/{post}PostController::show(mixed $post)

Middleware Grouping

You can group routes and assign a middleware to all of them:

Route::setMiddlewares(RedirectIfAuthenticated::class)
     ->group(function () {
         Route::get('test', function () {
             // Handle request
         });

         Route::resource('posts', PostController::class);
     });

Controller Grouping

Group routes by a common controller:

Route::controller(SomeController::class)
     ->group(function () {
         Route::get('someroute', 'methodName');
         Route::post('posts', 'store');
     });

You can also combine controller and middleware grouping:

Route::controller(SomeController::class)
     ->setMiddlewares(SomeMiddleware::class)
     ->group(function () {
         Route::get('route', 'method');
         Route::post('posts', 'store');
     });

Handling 404 Requests

Define a custom action for 404 responses:

Route::notFound(function () {
    // Handle 404 error
    echo 'Page not found';
});

If not defined, a simple 404 HTTP message will be returned.


License

This package is licensed under the MIT License.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages