Skip to main content
This guide will help you create your first Lyger application. We’ll build a simple API with a “Hello World” endpoint and explore the core concepts of the framework.

Prerequisites

Before you begin, make sure you have:
  • Completed the Installation guide
  • Lyger framework installed and running
  • Basic knowledge of PHP

Your First Route

Lyger makes it easy to define routes. Routes are defined in the routes/web.php file.
1

Understand the Default Route

When you first install Lyger, routes/web.php contains a default route:
routes/web.php
<?php

declare(strict_types=1);

use Lyger\Routing\Route;
use Lyger\Http\Response;

Route::get('/', function () {
    return Response::json([
        'name' => 'Lyger Framework v0.1',
        'status' => 'running',
        'message' => 'Welcome to Lyger - PHP on steroids with Rust FFI'
    ]);
});
Start your server and test it:
php rawr serve
Visit http://localhost:8000 - you should see the JSON response.
2

Add a Simple Route

Let’s add a new route. Open routes/web.php and add:
routes/web.php
Route::get('/hello', function () {
    return Response::json([
        'message' => 'Hello, World!'
    ]);
});
Visit http://localhost:8000/hello to see your new route in action!
3

Add Route Parameters

Routes can accept parameters using curly braces:
routes/web.php
Route::get('/greet/{name}', function ($request, $name) {
    return Response::json([
        'message' => "Hello, {$name}!"
    ]);
});
Try it: http://localhost:8000/greet/Alice

HTTP Methods

Lyger supports all standard HTTP methods:
routes/web.php
use Lyger\Routing\Route;
use Lyger\Http\Response;

// GET request
Route::get('/users', function () {
    return Response::json(['users' => []]);
});

// POST request
Route::post('/users', function ($request) {
    $data = $request->all();
    return Response::json(['created' => $data], 201);
});

// PUT request
Route::put('/users/{id}', function ($request, $id) {
    return Response::json(['updated' => $id]);
});

// DELETE request
Route::delete('/users/{id}', function ($request, $id) {
    return Response::json(['deleted' => $id]);
});

Creating Your First Controller

Controllers help organize your application logic. Let’s create one using the Rawr CLI.
1

Generate a Controller

Use the make:controller command:
php rawr make:controller UserController
This creates App/Controllers/UserController.php:
App/Controllers/UserController.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use Lyger\Http\Request;
use Lyger\Http\Response;

class UserController
{
    public function index(): Response
    {
        return Response::json(['message' => 'UserController controller']);
    }
}
2

Add Controller Methods

Edit the controller to add more methods:
App/Controllers/UserController.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use Lyger\Http\Request;
use Lyger\Http\Response;

class UserController
{
    public function index(): Response
    {
        return Response::json([
            'users' => [
                ['id' => 1, 'name' => 'Alice'],
                ['id' => 2, 'name' => 'Bob'],
            ]
        ]);
    }

    public function show(Request $request, string $id): Response
    {
        return Response::json([
            'user' => ['id' => $id, 'name' => 'Alice']
        ]);
    }

    public function store(Request $request): Response
    {
        $data = $request->all();
        
        return Response::json([
            'message' => 'User created',
            'user' => $data
        ], 201);
    }
}
3

Register Controller Routes

Update routes/web.php to use the controller:
routes/web.php
<?php

declare(strict_types=1);

use Lyger\Routing\Route;
use App\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Route::post('/users', [UserController::class, 'store']);
Controllers are automatically resolved from the container. The first parameter is always the Request object, followed by route parameters.

Working with Requests

The Request object provides access to all request data:
use Lyger\Http\Request;
use Lyger\Http\Response;

Route::post('/api/data', function (Request $request) {
    // Get all input data
    $all = $request->all();
    
    // Get specific input
    $name = $request->input('name');
    
    // Get request method
    $method = $request->method(); // POST
    
    // Get request URI
    $uri = $request->uri(); // /api/data
    
    return Response::json(['received' => $all]);
});

Response Types

Lyger provides several response types:
use Lyger\Http\Response;

Route::get('/api/users', function () {
    return Response::json([
        'users' => ['Alice', 'Bob']
    ]);
});

Building a Complete Example

Let’s build a simple task management API to demonstrate Lyger’s capabilities.
1

Create the Controller

php rawr make:controller TaskController
Edit App/Controllers/TaskController.php:
App/Controllers/TaskController.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use Lyger\Http\Request;
use Lyger\Http\Response;

class TaskController
{
    private array $tasks = [];

    public function __construct()
    {
        // In a real app, this would come from a database
        $this->tasks = [
            ['id' => 1, 'title' => 'Learn Lyger', 'completed' => false],
            ['id' => 2, 'title' => 'Build an API', 'completed' => false],
        ];
    }

    public function index(): Response
    {
        return Response::json([
            'tasks' => $this->tasks,
            'count' => count($this->tasks)
        ]);
    }

    public function show(Request $request, string $id): Response
    {
        $task = null;
        foreach ($this->tasks as $t) {
            if ($t['id'] == $id) {
                $task = $t;
                break;
            }
        }

        if (!$task) {
            return Response::error('Task not found', 404);
        }

        return Response::json(['task' => $task]);
    }

    public function store(Request $request): Response
    {
        $data = $request->all();
        
        $task = [
            'id' => count($this->tasks) + 1,
            'title' => $data['title'] ?? 'Untitled',
            'completed' => false
        ];

        return Response::json([
            'message' => 'Task created successfully',
            'task' => $task
        ], 201);
    }

    public function update(Request $request, string $id): Response
    {
        $data = $request->all();
        
        return Response::json([
            'message' => 'Task updated successfully',
            'task' => [
                'id' => $id,
                'title' => $data['title'] ?? 'Updated Task',
                'completed' => $data['completed'] ?? false
            ]
        ]);
    }

    public function destroy(Request $request, string $id): Response
    {
        return Response::json([
            'message' => 'Task deleted successfully',
            'id' => $id
        ]);
    }
}
2

Define the Routes

Add routes to routes/web.php:
routes/web.php
<?php

declare(strict_types=1);

use Lyger\Routing\Route;
use App\Controllers\TaskController;

// Task API routes
Route::get('/api/tasks', [TaskController::class, 'index']);
Route::get('/api/tasks/{id}', [TaskController::class, 'show']);
Route::post('/api/tasks', [TaskController::class, 'store']);
Route::put('/api/tasks/{id}', [TaskController::class, 'update']);
Route::delete('/api/tasks/{id}', [TaskController::class, 'destroy']);
3

Test Your API

Start the server if it’s not running:
php rawr serve
Test your endpoints:
curl http://localhost:8000/api/tasks

CLI Commands Reference

Lyger includes a powerful CLI tool called rawr. Here are the essential commands:
# Start development server
php rawr serve

# Start on custom port
php rawr serve --port=3000

# Legacy PHP server
php rawr serve:php

Understanding the Request Flow

Here’s how Lyger processes requests:
Browser Request

public/index.php (entry point)

Router (routes/web.php)

Controller Method

Response

Browser
The application bootstrap happens in public/index.php:
public/index.php
<?php

declare(strict_types=1);

require_once __DIR__ . '/../vendor/autoload.php';

use Lyger\Http\Request;
use Lyger\Routing\Router;
use Lyger\Container\Container;

// Create container
$container = Container::getInstance();

// Create router and load routes
$router = new Router($container);
$router->loadRoutesFromFile(__DIR__ . '/../routes/web.php');

// Capture request and dispatch
$request = Request::capture();
$response = $router->dispatch($request);
$response->send();

Next Steps

Congratulations! You’ve built your first Lyger application. Here’s what to explore next:

Database & ORM

Learn about Eloquent-style models and migrations

Middleware

Add middleware to your routes

CLI Commands

Explore scaffold commands

Authentication

Secure your application
Pro Tip: Lyger combines PHP simplicity with Rust performance. As you build, you’ll experience the framework’s high-performance features like the Rust-powered query builder and Always-Alive server mode.

Example Projects

Want to see Lyger in action? Check out these example projects:

Getting Help

  • GitHub Issues: Report bugs or request features
  • Documentation: Explore the rest of this documentation
  • Source Code: Study the framework source in the Lyger/ directory