<h2>O Que São Middlewares e Por Que Importam</h2>
<p>Middlewares são funções ou classes que interceptam a requisição HTTP antes dela chegar ao seu controlador e/ou manipulam a resposta após o processamento. Imagine um fluxo linear: cliente → servidor → resposta. Os middlewares atuam como porteiros inteligentes nesse fluxo, permitindo validações, autenticações, logs e transformações de dados sem sujar sua lógica principal.</p>
<p>Em PHP, especialmente em frameworks modernos como Laravel e Slim, middlewares seguem um padrão clássico: recebem a requisição, podem modificá-la ou rejeitá-la, e passam adiante (ou interrompem). Essa abordagem torna o código mais modular, reutilizável e testável — três pilares de qualidade que você vai querer em produção.</p>
<h2>Anatomia e Implementação Prática</h2>
<h3>Middleware Simples em PSR-15</h3>
<p>O padrão PSR-15 define a interface <code>MiddlewareInterface</code>. Veja um exemplo funcional:</p>
<pre><code class="language-php"><?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class LoggerMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
// Antes da requisição
$startTime = microtime(true);
$method = $request->getMethod();
$path = $request->getUri()->getPath();
echo "[LOG] {$method} {$path} iniciado\n";
// Passa para o próximo middleware/handler
$response = $handler->handle($request);
// Depois da requisição
$duration = microtime(true) - $startTime;
echo "[LOG] {$method} {$path} finalizado em {$duration}s\n";
return $response;
}
}</code></pre>
<h3>Middleware de Autenticação</h3>
<p>Um caso mais realista: validar token JWT antes de acessar recursos protegidos.</p>
<pre><code class="language-php"><?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class AuthMiddleware implements MiddlewareInterface
{
private string $secret = 'sua-chave-secreta';
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
$header = $request->getHeaderLine('Authorization');
if (!$header || !preg_match('/Bearer\s+(.+)/i', $header, $matches)) {
return $this->unauthorized();
}
try {
$token = $matches[1];
$decoded = JWT::decode($token, new Key($this->secret, 'HS256'));
// Adiciona usuário à requisição
$request = $request->withAttribute('user', $decoded);
return $handler->handle($request);
} catch (\Exception $e) {
return $this->unauthorized();
}
}
private function unauthorized(): ResponseInterface
{
$response = new \GuzzleHttp\Psr7\Response(401);
$response->getBody()->write(json_encode([
'error' => 'Unauthorized'
]));
return $response->withHeader('Content-Type', 'application/json');
}
}</code></pre>
<h2>Composição e Pipeline de Middlewares</h2>
<h3>Encadeando Múltiplos Middlewares</h3>
<p>Na prática, você vai rodar vários middlewares em sequência. Frameworks como Slim fazem isso nativamente:</p>
<pre><code class="language-php"><?php
require 'vendor/autoload.php';
use Slim\Factory\AppFactory;
$app = AppFactory::create();
// Ordem importa! Middlewares são executados de cima para baixo
$app->add(new App\Middleware\LoggerMiddleware());
$app->add(new App\Middleware\AuthMiddleware());
$app->add(new App\Middleware\CorsMiddleware());
$app->get('/api/users', function ($request, $response) {
$user = $request->getAttribute('user');
$response->getBody()->write(json_encode([
'message' => "Olá, {$user->name}"
]));
return $response->withHeader('Content-Type', 'application/json');
});
$app->run();</code></pre>
<h3>Middleware com Parâmetros</h3>
<p>Às vezes você precisa configurar um middleware dinamicamente:</p>
<pre><code class="language-php"><?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class RateLimitMiddleware implements MiddlewareInterface
{
private int $requestsPerMinute;
public function __construct(int $requestsPerMinute = 60)
{
$this->requestsPerMinute = $requestsPerMinute;
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
$ip = $request->getServerParams()['REMOTE_ADDR'];
$key = "rate_limit:{$ip}";
// Simula verificação em cache (Redis ideal)
$requests = apcu_fetch($key) ?: 0;
if ($requests >= $this->requestsPerMinute) {
$response = new \GuzzleHttp\Psr7\Response(429);
$response->getBody()->write('Too Many Requests');
return $response;
}
apcu_store($key, $requests + 1, 60);
return $handler->handle($request);
}
}
// Uso com parâmetro
$app->add(new App\Middleware\RateLimitMiddleware(100));</code></pre>
<h2>Casos de Uso Comuns e Boas Práticas</h2>
<h3>Quando (e Quando Não) Usar Middlewares</h3>
<p>Use middlewares para: autenticação, autorização, logging, CORS, rate limiting, compressão de resposta, validação de headers. <strong>Não</strong> use para lógica de negócio complexa — isso fica no controlador ou serviço.</p>
<p>Middleware é transversal; controlador é vertical. Mantenha essa separação clara e seu código será muito mais legível quando estiver debugando em produção às 2 da manhã.</p>
<h3>Ordem de Execução</h3>
<p>Lembre-se: middlewares executam <strong>de cima para baixo na requisição</strong> e <strong>de baixo para cima na resposta</strong>. Se você adicionar CORS antes de Auth, clientes não autenticados conseguirão fazer preflight requests — provavelmente o que você quer. Mas se adicionar um middleware que encripta a resposta antes de Logger, o log não conseguirá ler o corpo. Pense sempre na sequência.</p>
<pre><code class="language-php"></code></pre>
<h2>Conclusão</h2>
<p>Middlewares são um dos padrões mais poderosos em arquitetura web moderna. Você aprendeu que: <strong>(1)</strong> middlewares interceptam requisições e respostas, permitindo lógica transversal sem poluir controladores; <strong>(2)</strong> o padrão PSR-15 oferece uma interface padronizada e reutilizável entre frameworks; <strong>(3)</strong> a ordem de execução é crítica e deve refletir sua lógica de negócio.</p>
<p>Da próxima vez que precisar autenticar um usuário ou logar requisições, pense em middleware primeiro. Seu código futuro agradecerá.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://www.php-fig.org/psr/psr-15/" target="_blank" rel="noopener noreferrer">PSR-15: HTTP Server Request Handlers</a></li>
<li><a href="https://www.slimframework.com/docs/v4/concepts/middleware.html" target="_blank" rel="noopener noreferrer">Slim Framework: Middleware</a></li>
<li><a href="https://laravel.com/docs/middleware" target="_blank" rel="noopener noreferrer">Laravel: HTTP Middleware Documentation</a></li>
<li><a href="https://github.com/firebase/php-jwt" target="_blank" rel="noopener noreferrer">Firebase JWT Library</a></li>
<li><a href="https://phptherightway.com/#security" target="_blank" rel="noopener noreferrer">PHP The Right Way: Security</a></li>
</ul>