gesuporte / edec-router
Simple HTTP router for PHP applications
Requires
- php: >=8.4
- firebase/php-jwt: ^7.1
Requires (Dev)
- phpunit/phpunit: ^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Biblioteca de roteamento HTTP para PHP 8.4+.
Recursos
- Rotas declaradas com
#[Route(...)]. - Métodos HTTP
GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACEeCONNECT. - Parâmetros de rota, com passagem por nome para o método do Controller.
- Injeção de
Requestnas ações dos Controllers. - Query string separada automaticamente do caminho.
- Barra
/final opcional. - Parâmetros URL-encoded decodificados após o match.
- Priorização de rotas estáticas sobre rotas parametrizadas.
- Detecção de rotas duplicadas.
- Validação dos parâmetros da rota contra a assinatura da ação.
- Validação dos middlewares no momento do registro.
- Pipeline de múltiplos middlewares.
- Respostas
404 Not Founde405 Method Not Allowed. - Header
Allowem respostas405. - Objeto
Responsepara centralizar status, headers e corpo HTTP. ExceptionHandlerintegrado para converter exceções em respostas JSON.- Compatibilidade com Controllers legados que ainda usam
echo: o Router captura a saída e a transforma emResponse. - Atributo
Routerepetível para permitir múltiplas rotas por método.
Fluxo HTTP
O fluxo recomendado é:
Request
↓
Router
↓
Middleware 1
↓
Middleware 2
↓
Controller
↓
Response
↓
Aplicação chama -> send()
Exceções lançadas durante o processamento são convertidas pelo ExceptionHandler em Response.
Exemplo
Controller
use EdecRouter\Controllers\Controller;
use EdecRouter\Http\Request;
use EdecRouter\Http\Response;
use EdecRouter\Http\Route;
final class UsuarioController extends Controller
{
#[Route('/usuarios/{id}', 'GET')]
public function show(Request $request, string $id): Response
{
return Response::json([
'id' => $id,
'metodo' => $request->method,
'pagina' => $request->query['pagina'] ?? null,
]);
}
}
Inicialização
use EdecRouter\Http\ExceptionHandler;
use EdecRouter\Http\Router;
ExceptionHandler::register(debug: false);
$router = new Router();
$router->registerControllers([
UsuarioController::class,
]);
$response = $router->resolve($_SERVER['REQUEST_URI'] ?? '/', $_SERVER['REQUEST_METHOD'] ?? 'GET');
$response->send();
Também é possível criar uma requisição explicitamente, o que facilita testes:
$request = new Request(
method: 'GET',
uri: '/usuarios/10?pagina=2',
);
$response = $router->resolve($request);
$response->send();
Request
Request centraliza os dados recebidos pelo cliente e pode ser criado a partir do PHP ou manualmente em testes.
Principais recursos:
$request->method;
$request->uri;
$request->path;
$request->query;
$request->body;
$request->headers;
$request->input('email');
$request->queryValue('pagina', 1);
$request->getHeader('Authorization');
$request->getContent();
$request->contentType();
$request->isJson();
$request->acceptsJson();
$request->bearerToken();
$request->cookie('sessao');
$request->file('arquivo');
$request->ip();
JSON e application/x-www-form-urlencoded são interpretados automaticamente. Para outros tipos de conteúdo, o corpo bruto permanece disponível em getContent(). JSON inválido gera uma exceção HTTP 400.
Para aplicações atrás de proxy, ip(true) pode considerar o primeiro endereço de X-Forwarded-For. Use essa opção somente quando o proxy for confiável.
Controller helper
O método json() do Controller agora retorna Response:
return $this->json(
true,
'Usuário encontrado.',
200,
$usuario,
);
Isso substitui o padrão antigo de executar http_response_code(), header() e json_encode() dentro do Controller.
Middleware
A interface recebe a requisição e retorna a resposta:
final class AuthMiddleware implements Middleware
{
public function handle(Request $request, callable $next): Response
{
// validação...
return $next($request);
}
}
Um middleware pode alterar a resposta depois que o próximo estágio terminar:
$response = $next($request);
return $response->withHeader('X-Application', 'EdecRouter');
Response
Exemplos:
return Response::json(['ok' => true]);
return Response::json(['erro' => 'Não encontrado'], 404);
return Response::text('Olá mundo');
return Response::empty(204);
A resposta só é enviada ao cliente quando send() é chamado. Isso mantém Router, Controller e Middleware independentes do envio físico da resposta.
Exceções HTTP
Para erros controlados da aplicação:
throw new HttpException(422, 'Dados inválidos.');
O ExceptionHandler transforma a exceção em JSON. Em produção, exceções 5xx não expõem detalhes internos. Em desenvolvimento, pode-se habilitar:
ExceptionHandler::register(debug: true);
Testes
Depois de instalar as dependências:
composer install
Execute:
composer test
Os testes cobrem roteamento, parâmetros, URL encoding, prioridade de rotas, middlewares, Request, Response, tratamento de exceções, 404 e 405.
edec-router