PHP code example of luracast / restler

1. Go to this page and download the library: Download luracast/restler library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

luracast / restler example snippets


use Luracast\Restler\Restler;
use Luracast\Restler\Routes;

class Products {
    function get(int $id): array {
        return Database::findProduct($id);
    }
}

Routes::mapApiClasses([Products::class]);
(new Restler)->handle();

// Laravel/Symfony: 50+ lines of controllers, routes, requests, resources
// Restler: 5 lines
class Users {
    function create(string $email, string $name): User {
        return User::create(compact('email', 'name'));
    }
}

use Luracast\Restler\Attribute\{Get, Post};

class Orders {
    #[Get('orders/{id}')]
    function getOrder(int $id): Order|null {
        return Order::find($id);
    }

    #[Post('orders')]
    function createOrder(string $product, int $quantity = 1): Order {
        return Order::create(compact('product', 'quantity'));
    }
}

class Products {
    /**
     * Get product details
     *
     * @param int $id Product ID
     * @return Product product information
     * @throws 404 Product not found
     */
    function get(int $id): Product {
        return Product::findOrFail($id);
    }
}
// Visit /explorer for interactive Swagger UI

function exportUsers(): Generator {
    foreach (User::cursor() as $user) {
        yield $user->toArray();
    }
}
// GET /users.csv streams all users as CSV
// GET /users.xlsx downloads Excel file


class Hello {
    function sayHello(string $name = 'World'): string {
        return "Hello, $name!";
    }

    function getTime(): array {
        return ['time' => date('Y-m-d H:i:s'), 'timezone' => date_default_timezone_get()];
    }
}


cast\Restler\Routes::mapApiClasses([Hello::class]);
(new Luracast\Restler\Restler)->handle();

// Enable production mode for route caching
$api = new Restler(productionMode: true);

// v1/Users.php
namespace v1;
class Users {
    function get(int $id): array {
        return ['id' => $id, 'name' => 'John'];
    }
}

// v2/Users.php
namespace v2;
class Users {
    function get(int $id): User {
        return User::with('profile')->find($id);
    }
}

// index.php
use Luracast\Restler\Routes;

Routes::mapApiClasses([
    'v1/users' => 'v1\\Users',
    'v2/users' => 'v2\\Users'
]);

use Luracast\Restler\Contracts\AuthenticationInterface;

class ApiKeyAuth implements AuthenticationInterface {
    public function __isAuthenticated(): bool {
        $key = $_SERVER['HTTP_X_API_KEY'] ?? null;
        return $key && ApiKey::validate($key);
    }
}

use Luracast\Restler\Restler;
use Luracast\Restler\Routes;

Routes::addAuthenticator(ApiKeyAuth::class);
Routes::setFilters(RateLimit::class);  // Built-in rate limiting
Routes::mapApiClasses([ProtectedAPI::class]);
(new Restler)->handle();

class Products {
    /**
     * List all products with pagination
     *
     * @param int $page Page number (default: 1)
     * @param int $limit Items per page (default: 20)
     */
    function index(int $page = 1, int $limit = 20): array {
        return Product::paginate($limit, page: $page)->toArray();
    }

    /**
     * Create new product
     *
     * @param string $name Product name
     * @param float $price Product price
     * @param string $category Category name
     */
    function post(string $name, float $price, string $category): Product {
        return Product::create(compact('name', 'price', 'category'));
    }

    /**
     * Update product
     *
     * @param int $id Product ID {@from path}
     */
    function put(int $id, string $name = null, float $price = null): Product {
        $product = Product::findOrFail($id);
        if ($name) $product->name = $name;
        if ($price) $product->price = $price;
        $product->save();
        return $product;
    }

    /**
     * Delete product
     *
     * @param int $id Product ID {@from path}
     */
    function delete(int $id): array {
        Product::findOrFail($id)->delete();
        return ['message' => 'Product deleted'];
    }
}

class Media {
    /**
     * Upload file
     *
     * @param array $file Upload file {@from body} {@type file}
     */
    function post(array $file): array {
        $path = Storage::put('uploads', $file['tmp_name']);
        return [
            'filename' => $file['name'],
            'url' => Storage::url($path),
            'size' => $file['size']
        ];
    }
}

class Reports {
    /**
     * Export all users (memory efficient)
     */
    function exportUsers(): Generator {
        // Processes millions of rows without memory issues
        foreach (User::cursor() as $user) {
            yield [
                'id' => $user->id,
                'email' => $user->email,
                'created' => $user->created_at
            ];
        }
    }
}

// GET /reports/exportUsers.csv → streams CSV
// GET /reports/exportUsers.xlsx → streams Excel

class Products {
    /**
     * @url GET products/featured
     */
    function getFeatured(): array {
        return Product::where('featured', true)->get();
    }

    /**
     * @url GET products/search/{query}
     * @param string $query Search term {@from path}
     */
    function search(string $query): array {
        return Product::where('name', 'LIKE', "%$query%")->get();
    }

    /**
     * @url POST products/{id}/publish
     * @param int $id Product ID {@from path}
     */
    function publish(int $id): array {
        $product = Product::findOrFail($id);
        $product->published = true;
        $product->save();
        return ['message' => 'Published successfully'];
    }
}

use Luracast\Restler\Restler;
use Luracast\Restler\Routes;
use Luracast\Restler\OpenApi3\Explorer;

Routes::mapApiClasses([
    'graphql' => GraphQLEndpoint::class,
    'explorer' => Explorer::class
]);
(new Restler)->handle();

// POST /graphql
// Query and mutation support built-in

use Luracast\Restler\Defaults;

Defaults::$accessControlAllowOrigin = 'https://app.example.com';
Defaults::$accessControlAllowMethods = 'GET, POST, PUT, DELETE';
Defaults::$accessControlAllowHeaders = 'Content-Type, Authorization';
Defaults::$accessControlMaxAge = 86400;

use Luracast\Restler\Restler;
use Luracast\Restler\Routes;

Routes::mapApiClasses([MyAPI::class]);
(new Restler)->handle();

use Luracast\Restler\Restler;
use Luracast\Restler\Routes;
use Luracast\Restler\OpenApi3\Explorer;

Routes::mapApiClasses([
    Products::class,
    Users::class,
    'explorer' => Explorer::class  // Add explorer
]);
(new Restler)->handle();

// Caches routes, disables debug mode
$api = new Restler(productionMode: true);

// Clear route cache after code changes:
// rm cache/routes.php

// Bad: Loads everything into memory
function getUsers(): array {
    return User::all()->toArray();  // 💥 100MB+
}

// Good: Streams data
function getUsers(): Generator {
    foreach (User::cursor() as $user) {
        yield $user->toArray();  // ✅ Constant memory
    }
}

use Luracast\Restler\Defaults;

// Enable route caching
Defaults::$cacheDirectory = __DIR__ . '/cache';

// Use your own caching for data
function getPopularProducts(): array {
    return Cache::remember('popular_products', 3600, function() {
        return Product::orderBy('views', 'desc')->take(10)->get();
    });
}

// Use eager loading to avoid N+1 queries
function index(): array {
    return Order::with(['user', 'items.product'])->get();
}

// v5 - Still works but add types for better validation
public function getUser($id) {
    return User::find($id);
}

// v6 - Recommended
public function getUser(int $id): ?User {
    return User::find($id);
}
bash
# Install extension (choose one)
pecl install swoole        # Original
pecl install openswoole    # Fork with same API

# Run server
php public/index_swoole.php
bash
php public/index_workerman.php start
bash
pecl install swoole
php public/index_swoole.php