ADR-005 - Padrão de Middleware PSR-15
ADR-005: Padrão de Middleware PSR-15 para XOOPS 4.0
Seção intitulada “ADR-005: Padrão de Middleware PSR-15 para XOOPS 4.0”Adote manipuladores de requisição de servidor HTTP PSR-15 (middleware) para pipeline de processamento de requisição melhorado.
Proposto - Sob avaliação para lançamento XOOPS 4.0
Contexto
Seção intitulada “Contexto”Abordagem Atual
Seção intitulada “Abordagem Atual”XOOPS 2.5 usa uma abordagem monolítica de manipulação de requisição:
// Atual: Processamento sequencialrequire_once 'mainfile.php';// → Inicialização do kernel// → Autenticação de usuário// → Carregamento de módulo// → Renderização de página
// Tudo em um fluxo, preocupações misturadasProblemas com Abordagem Atual
Seção intitulada “Problemas com Abordagem Atual”- Preocupações Misturadas - Autenticação, logging, roteamento todos entrelaçados
- Difícil de Testar - Difícil fazer teste unitário de etapas de processamento de requisição individual
- Difícil de Estender - Módulos apenas podem usar preload/eventos
- Separação Pobre - Lógica de processamento de requisição espalhada por codebase
- Não Componível - Não é fácil encadear ou reordenar etapas de processamento
O que é Middleware PSR-15?
Seção intitulada “O que é Middleware PSR-15?”PSR-15 define uma interface padrão para middleware HTTP:
<?phpinterface RequestHandlerInterface { public function handle(ServerRequestInterface $request): ResponseInterface;}
interface MiddlewareInterface { public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface;}Cadeia de Middleware:
Requisição ↓[Logger] → registra requisição ↓[Auth] → valida sessão de usuário ↓[CORS] → verifica origem cruzada ↓[Router] → despacha para manipulador ↓[Handler] → gera resposta ↓RespostaDecisão
Seção intitulada “Decisão”Adotar Pilha de Middleware PSR-15 para XOOPS 4.0
Seção intitulada “Adotar Pilha de Middleware PSR-15 para XOOPS 4.0”Implementar um pipeline de processamento de requisição baseado em middleware seguindo padrão PSR-15.
Visão Geral da Arquitetura
Seção intitulada “Visão Geral da Arquitetura”graph TD subgraph "Pipeline de Processamento de Requisição" A["Requisição HTTP<br/>(PSR-7 ServerRequest)"] B["Pilha de Middleware<br/>(PSR-15)"] C["Middleware de Logger"] D["Middleware de Sessão"] E["Middleware de Auth"] F["Middleware de CORS"] G["Middleware de Router"] H["Manipulador<br/>(Controller/Action)"] I["Resposta<br/>(PSR-7 Response)"] end
A --> B B --> C C --> D D --> E E --> F F --> G G --> H H --> IComponentes Principais de Middleware
Seção intitulada “Componentes Principais de Middleware”1. Middleware de Aplicação (Camada Central)
Seção intitulada “1. Middleware de Aplicação (Camada Central)”<?phpdeclare(strict_types=1);
namespace XoopsCore;
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;
class SessionMiddleware implements MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { // 1. Recuperar sessão (ou iniciar nova) $sessionId = $request->getCookieParams()['PHPSESSID'] ?? null; $session = $this->sessionManager->load($sessionId);
// 2. Anexar sessão à requisição $request = $request->withAttribute('session', $session);
// 3. Passar para próximo middleware $response = $handler->handle($request);
// 4. Definir cookie de sessão se necessário if ($session->isModified()) { $response = $response->withAddedHeader( 'Set-Cookie', 'PHPSESSID=' . $session->getId() . '; HttpOnly; SameSite=Strict' ); }
return $response; }}2. Middleware de Autenticação
Seção intitulada “2. Middleware de Autenticação”<?phpclass AuthMiddleware implements MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { // Obter sessão do middleware anterior $session = $request->getAttribute('session');
// Autenticar usuário da sessão $user = $this->authenticate($session);
// Anexar usuário à requisição $request = $request->withAttribute('user', $user);
return $handler->handle($request); }
private function authenticate(?Session $session): User { if ($session && $session->has('uid')) { return $this->userRepository->findById($session->get('uid')); }
return new AnonymousUser(); }}3. Middleware de Autorização
Seção intitulada “3. Middleware de Autorização”<?phpclass AuthorizationMiddleware implements MiddlewareInterface{ public function __construct(private AuthorizationChecker $checker) { }
public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $user = $request->getAttribute('user'); $route = $request->getAttribute('route');
// Verificar se usuário tem permissão para esta rota if (!$this->checker->isGranted($user, $route)) { return new JsonResponse( ['error' => 'Não autorizado'], 403 ); }
return $handler->handle($request); }}4. Middleware de Módulo
Seção intitulada “4. Middleware de Módulo”<?php// Módulos podem fornecer seu próprio middlewareclass PublisherAccessMiddleware implements MiddlewareInterface{ public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $user = $request->getAttribute('user');
// Controle de acesso específico do módulo if (!$user->hasPermission('publisher_view')) { return new HtmlResponse('Acesso negado', 403); }
return $handler->handle($request); }}Exemplo de Implementação
Seção intitulada “Exemplo de Implementação”<?php// bootstrap.php - Configuração de aplicação
use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\RequestHandlerInterface;use Xoops\Core\Middleware\{ LoggerMiddleware, SessionMiddleware, AuthMiddleware, CorsMiddleware, ErrorHandlingMiddleware};
// Criar pipeline de middleware$middlewareStack = [ // 1. Manipulação de erro (mais externo) new ErrorHandlingMiddleware(),
// 2. Logging new LoggerMiddleware($logger),
// 3. Manipulação CORS new CorsMiddleware($corsConfig),
// 4. Gerenciamento de sessão new SessionMiddleware($sessionManager),
// 5. Autenticação new AuthMiddleware($userRepository),
// 6. Autorização new AuthorizationMiddleware($authChecker),
// 7. Roteamento e despacho new RoutingMiddleware($router),
// 8. Middleware de módulo (dinâmico) ...$this->loadModuleMiddleware(),];
// Processar requisição através pilha de middleware$request = ServerRequestFactory::fromGlobals();$dispatcher = new MiddlewareDispatcher($middlewareStack);$response = $dispatcher->dispatch($request);
// Enviar respostahttp_response_code($response->getStatusCode());foreach ($response->getHeaders() as $name => $values) { foreach ($values as $value) { header("$name: $value", false); }}echo $response->getBody();Integração de Módulo
Seção intitulada “Integração de Módulo”Módulos podem fornecer middleware:
<?php// Módulo Publisher - xoops_version.php
$modversion['middleware'] = [ 'PublisherAccessMiddleware' => true, // Auto-carregamento 'PublisherLogMiddleware' => true,];
// Ou customizado:$modversion['middleware_factory'] = function() { return [ new PublisherCacheMiddleware(), new PublisherPermissionMiddleware(), ];};Consequências
Seção intitulada “Consequências”Efeitos Positivos
Seção intitulada “Efeitos Positivos”- Separação de Preocupações - Cada middleware manipula uma responsabilidade
- Testabilidade - Fácil fazer teste unitário de componentes de middleware individuais
- Componibilidade - Middleware pode ser combinado e reordenado
- Em Conformidade com Padrões - Usa padrões PSR-15 e PSR-7
- Extensibilidade - Módulos podem adicionar middleware customizado facilmente
- Depuração - Fluxo de requisição claro através pipeline
- Performance - Pode otimizar camadas de middleware específicas
- Interoperabilidade - Pode usar middleware PSR-15 de terceiros
Efeitos Negativos
Seção intitulada “Efeitos Negativos”- Curva de Aprendizado - Desenvolvedores devem entender PSR-15
- Overhead de Performance - Mais chamadas de função em pipeline
- Complexidade - Mais partes móveis que abordagem monolítica
- Esforço de Migração - Requer refatoração de código existente
- Dependências - Requer biblioteca HTTP PSR-7
Riscos e Mitigações
Seção intitulada “Riscos e Mitigações”| Risco | Severidade | Mitigação |
|---|---|---|
| Cadeias de middleware complexas | Média | Documentação clara, exemplos |
| Degradação de performance | Média | Benchmark, otimizar caminhos quentes |
| Uso incorreto do desenvolvedor | Média | Revisão de código, guia de melhores práticas |
| Mudanças de ruptura de migração | Alta | Período de deprecação, helpers |
| Problemas de ordenação de middleware | Média | Gráfico de dependência claro |
Plano de Implementação
Seção intitulada “Plano de Implementação”Fase 1: Fundação (Q2 2026)
Seção intitulada “Fase 1: Fundação (Q2 2026)”- Implementar wrapper de mensagem HTTP PSR-7
- Criar MiddlewareDispatcher
- Implementar middleware principal (sessão, auth)
- Atualizar kernel para usar middleware
Fase 2: Integração (Q3 2026)
Seção intitulada “Fase 2: Integração (Q3 2026)”- Migrar funcionalidade existente para middleware
- Adicionar suporte de middleware de módulo
- Criar utilitários de teste de middleware
- Escrever documentação abrangente
Fase 3: Migração (Q4 2026)
Seção intitulada “Fase 3: Migração (Q4 2026)”- Fornecer camada de compatibilidade para código antigo
- Ajudar módulos a atualizar para novo middleware
- Otimização de performance
- Auditoria de segurança
Fase 4: Lançamento (Q1 2027)
Seção intitulada “Fase 4: Lançamento (Q1 2027)”- Lançamento XOOPS 4.0 com middleware
- Deprecar sistema antigo de preload/hook
- Feedback da comunidade e atualizações
Critérios de Sucesso
Seção intitulada “Critérios de Sucesso”- Todas funcionalidade principal migrada para middleware
- Cobertura de teste 90%+ para middleware
- Documentação completa com exemplos
- Performance dentro de 10% de versão anterior
- Módulos usam com sucesso novo sistema de middleware
- Taxa de adoção da comunidade >80%
Melhores Práticas de Middleware
Seção intitulada “Melhores Práticas de Middleware”- Manter middleware focado (responsabilidade única)
- Usar imutabilidade (criar nova requisição/resposta)
- Manipular erros gracefully
- Documentar dependências
- Adicionar type hints
- Escrever testes para middleware
- Usar interfaces padrão PSR-15
Não Faça
Seção intitulada “Não Faça”- Não modificar objetos de requisição/resposta compartilhados
- Não acessar globais diretamente
- Não criar dependências em ordem de middleware
- Não capturar todas exceções
- Não misturar lógica de negócios com middleware
- Não fazer middleware fazer muito
Exemplos
Seção intitulada “Exemplos”Middleware Customizado
Seção intitulada “Middleware Customizado”<?php// Exemplo: Middleware de limitação de taxa
use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Http\Server\MiddlewareInterface;use Psr\Http\Server\RequestHandlerInterface;
class RateLimitMiddleware implements MiddlewareInterface{ public function __construct( private RateLimiter $limiter, private int $limit = 100, private int $window = 3600 ) { }
public function process( ServerRequestInterface $request, RequestHandlerInterface $handler ): ResponseInterface { $user = $request->getAttribute('user'); $identifier = $user->getId() ?? $request->getClientIp();
// Verificar limite de taxa $remaining = $this->limiter->check($identifier, $this->limit, $this->window);
if ($remaining < 0) { return new JsonResponse( ['error' => 'Limite de taxa excedido'], 429 ); }
// Adicionar cabeçalhos de limite de taxa $response = $handler->handle($request); return $response ->withAddedHeader('X-RateLimit-Limit', (string)$this->limit) ->withAddedHeader('X-RateLimit-Remaining', (string)$remaining); }}Decisões Relacionadas
Seção intitulada “Decisões Relacionadas”- ADR-001: Arquitetura Modular - Fundação
- ADR-004: Sistema de Segurança - Usa middleware para auth
- ADR-006: Auth de Dois Fatores - Pode ser middleware
Referências
Seção intitulada “Referências”Padrões PSR
Seção intitulada “Padrões PSR”Estruturas de Middleware
Seção intitulada “Estruturas de Middleware”- Slim Framework - Exemplos de middleware
- Zend Expressive - Framework PSR-15
- Guzzle - Middleware de cliente HTTP
Ferramentas
Seção intitulada “Ferramentas”- RelayPHP - Biblioteca de middleware
- PSR-15 Middleware - Coleção de middlewares
Histórico de Versões
Seção intitulada “Histórico de Versões”| Versão | Data | Mudanças |
|---|---|---|
| 1.0.0 | 2024-01-28 | Proposta inicial |
#xoops #adr #psr-15 #middleware #architecture #psr-7