GERAL
A configuração de rotas HTTP do Accelero é bem simples/padrão.
Usamos oLeague/Route (https://route.thephpleague.com/) sem nenhum tipo de configuração esquisita, apenas alguns helpers.
ARQUIVOS DE ROTAS
Todas as rotas são definidas em arquivos localizados em private/config/routes.
Todos os arquivos PHP encontrados nesse diretório são carregados, e a divisão em múltiplos arquivos é apenas pra organizar/agrupar melhor.
Rotas definidas em arquivos que estejam em subdiretórios só são carregadas se houver um módulo ativo com o mesmo nome do subdiretório (rotas definidas dentro do subdiretório private/config/routes/modulo123 só serão carregadas se o modulo123 estiver ativo).
FORMATO DO ARQUIVO DE ROTAS
Todos os arquivos de rotas devem retornar um array de objetos do tipo Route.
Esse objeto define, basicamente:
| ARGUMENTO | EXPLICAÇÃO |
|---|---|
| method | GET/POST/PUT/DELETE* |
| pattern | A rota em si, com placeholders entre-chaves -- /pessoas/{id}/{outracoisa} |
| handler | Callback da rota |
| module | Rota só será carregada se esse módulo estiver ativo (serve como checagem adicional além do subdiretório) |
| middleware | Middleware(s) por onde o request vai passar ANTES de cair no callback |
Um exemplo básico de rota:
new Route('*', '/areas', [Area::class, 'listAll'], middleware: LoggedInMiddleware::class),
Qualquer request (*) que bater em /areas executará o método Area::listAll, mas antes passará pelo LoggedInMiddleware.
MIDDLEWARE
É possível definir múltiplos middlewares, se necessário, basta passar um array de class-string MiddlewareInterface:
new Route('POST', '/teste', [Teste::class, 'whatever'], middleware: [LoggedInMiddleware::class, AdminMiddleware::class]),
LAZY LOADING E INJEÇÃO DE DEPENDÊNCIA
Todas as classes/middlewares definidos nas rotas são lazy-loaded (carregados só na hora que são necessários) e sempre instanciados usando injeção de dependência.
O container do Accelero tem auto-wiring, o que significa que ele sabe construir a maior parte dos objetos só olhando pro construtor (não precisa definir no container TODAS as classes, só aquilo que tem parâmetros não-automaticamente-resolvíveis).
CALLBACKS - FORMATOS
Todos os callbacks de rotas devem ter a seguinte assinatura:
public function methodName(ServerRequestInterface $request, array $params) : ResponseInterface;
O array $params é opcional, mas é nele que estarão disponíveis os placeholders da rota.
O método DataFlusher::flush() é um helper pra gerar um ResponseInterface.
Exemplo:
//rota.php
new Route('*', '/areas/{idDaArea}', [Area::class, 'teste'], middleware: LoggedInMiddleware::class),
//Area.php
public function teste(ServerRequestInterface $request, array $params) : ResponseInterface {
$id = $params['idDaArea'];
return DataFlusher::flush(
request: $request,
code: DataFlusher::HTTP_OK, //HTTP 200
msg: 'O ID informado é '.$id,
);
}
FRONT-CONTROLLER E EXCEPTIONS
(Quase) Todos os requests batem no index.php, e daí é feito o roteamento por um FrontController.
Praticamente todo o tratamento do request está "envolto" num try/catch gigante. Isso significa que qualquer Exception não-tratada que estourar será capturada e tratada pelo FrontController. Dependendo do tipo de Exception, o tratamento é um pouquinho diferente.
No entanto, é RECOMENDÁVEL sempre fazer seu próprio try/catch pra evitar que o tratamento de erros caia nessa vala-comum.