Essentials

Controllers

Organize request handling logic with BaseController

In the API skeleton, application controllers live in app/Controllers/ and usually extend Glueful\Controllers\BaseController.

Basic Controller

<?php

declare(strict_types=1);

namespace App\Controllers;

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

class UserController extends BaseController
{
    public function index(Request $request): Response
    {
        $users = $this->db->table('users')->get();

        return $this->success($users);
    }
}

What BaseController Gives You

BaseController already includes:

  • $this->db for database access
  • $this->request for the current Symfony request
  • response helpers like $this->success() and $this->created()
  • request helpers like $this->getRequestData()
  • lightweight validation via $this->validateRequest()

Create / Update Example

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

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

        $taskId = $this->db->table('tasks')->insert([
            'title' => $data['title'],
            'description' => $data['description'] ?? null,
        ]);

        return $this->created([
            'id' => $taskId,
            'title' => $data['title'],
        ]);
    }
}

Constructor Injection

Controllers are resolved from the container, so constructor injection works:

use Psr\Log\LoggerInterface;

class UserController extends BaseController
{
    public function __construct(
        \Glueful\Bootstrap\ApplicationContext $context,
        private LoggerInterface $logger
    ) {
        parent::__construct($context);
    }

    public function index(Request $request): Response
    {
        $this->logger->info('Listing users');

        return $this->success($this->db->table('users')->get());
    }
}

If you override the constructor, call parent::__construct($context) so the base dependencies are initialized.

ResourceController

Glueful also ships a built-in Glueful\Controllers\ResourceController for generic CRUD-heavy cases. Use it when you want convention-driven resource endpoints quickly, but prefer explicit controllers first while you are learning the framework.

For most new applications, start with explicit controllers in app/Controllers and move to generic resource wiring only when the tradeoff is clear.