Getting Started

Build Your First API

Add a real controller and route to the API skeleton

This guide stays close to the actual glueful/api-skeleton structure so you can copy it directly.

Start From the Skeleton

composer create-project glueful/api-skeleton task-api
cd task-api
composer install
php glueful install --quiet

Create a Controller

Create app/Controllers/TaskController.php:

<?php

declare(strict_types=1);

namespace App\Controllers;

use Glueful\Controllers\BaseController;
use Glueful\Http\Response;
use Symfony\Component\HttpFoundation\Request;

class TaskController extends BaseController
{
    /**
     * @var array<int, array<string, mixed>>
     */
    private static array $tasks = [];

    public function index(Request $request): Response
    {
        return $this->success(self::$tasks);
    }

    public function store(Request $request): Response
    {
        $data = $this->getRequestData();

        if ($error = $this->validateRequest($data, [
            'title' => 'required|max:255',
        ])) {
            return $error;
        }

        $task = [
            'id' => count(self::$tasks) + 1,
            'title' => $data['title'],
            'completed' => false,
            'created_at' => date('c'),
        ];

        self::$tasks[] = $task;

        return $this->created($task);
    }
}

This example intentionally uses BaseController::getRequestData() and BaseController::validateRequest() because they are available in the current framework and match the starter app model.

Register the Routes

Update routes/api.php:

<?php

use Glueful\Routing\Router;
use App\Controllers\TaskController;
use App\Controllers\WelcomeController;

$router->group(['prefix' => 'v1'], function (Router $router) {
    $router->get('/status', [WelcomeController::class, 'status']);

    $router->get('/tasks', [TaskController::class, 'index']);
    $router->post('/tasks', [TaskController::class, 'store']);
});

$router->get('/welcome', [WelcomeController::class, 'index']);

Start the Server

php glueful serve

Test the API

Create a task:

curl -X POST http://127.0.0.1:8080/v1/tasks \
  -H "Content-Type: application/json" \
  -d '{"title":"Ship docs"}'

List tasks:

curl http://127.0.0.1:8080/v1/tasks

What To Build Next

Once this flow is clear, move on to: