You’re reading the v0.1 development preview. APIs may change.
~ 2 min readUpdated 2026-10-29

Controllers & responses

Controllers keep route files focused. Elang resolves constructor dependencies and handler parameters from the service container.

An invokable controller

namespace App\Controllers;

use Elang\Http\Response;
use Symfony\Component\HttpFoundation\JsonResponse;

final class HelloController
{
    public function __invoke(): JsonResponse
    {
        return Response::json(['message' => 'Hello from Elang']);
    }
}

Register it with $router->get('/hello', HelloController::class).

Read a request

use Symfony\Component\HttpFoundation\Request;

$router->get('/search', function (Request $request) {
    return ['query' => $request->query->get('q', '')];
});

For JSON, decode $request->getContent() using JSON_THROW_ON_ERROR, verify the top-level structure, and validate fields. Form data is available through $request->request.

Response helpers

Response::json(['created' => true], 201);
Response::html('<h1>Hello</h1>');
Response::redirect('/dashboard');

The redirect helper accepts local absolute paths and rejects external or protocol-relative destinations. Returning raw HTML requires you to escape interpolated values; Twig templates handle escaping automatically.

Errors

Throw Elang\Http\HttpException with a status and safe public message. API errors use a JSON envelope with message and request_id. Internal errors are logged through PSR-3; stack traces are not sent to visitors.

Need a hand?

Check the troubleshooting guide, look up a term in the glossary, or work through the complete task board project.

Search Elang documentation

Start typing to find your next step.