Gateways de API e descoberta de serviços
Encaminhe, agregue e localize serviços dinamicamente.
Gateways de API e descoberta de serviços é uma aula grátis de PHP Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de PHP Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de PHP Academy inclui 4 aulas no total.
Gateways e descoberta
Depois que você tiver uma dúzia de serviços, surgem dois problemas. Os clientes não deveriam precisar conhecer o endereço de cada serviço nem chamar cinco deles para renderizar uma tela — essa é a função da porta de entrada da API. E os serviços que aumentam ou reduzem a escala e mudam de IP precisam de uma forma de encontrar uns aos outros — isso é a descoberta de serviços.
Esta lição aborda os dois temas, com PHP na borda da porta de entrada.
O que faz uma porta de entrada de API
Uma porta de entrada de API é um único ponto de entrada diante dos seus serviços. Responsabilidades típicas:
- Roteamento de requisições para o serviço de retaguarda correto.
- Preocupações transversais: autenticação, limitação de taxa, CORS e encerramento de TLS.
- Agregação: combinação de várias chamadas aos serviços de retaguarda em uma única resposta ao cliente.
- Tradução de protocolos: REST externo na entrada, gRPC interno na saída.
Ela mantém os clientes simples e centraliza políticas que, de outra forma, seriam duplicadas em todos os serviços.
Roteamento na borda
No seu núcleo, uma porta de entrada mapeia um caminho de entrada para um serviço de destino. As portas de entrada de produção (Kong, Traefik, Nginx, AWS API Gateway) fazem isso de forma declarativa, mas a lógica é simples o suficiente para ser ilustrada em PHP.
<?php
$routes = [
'#^/api/orders#' => 'http://orders-svc',
'#^/api/customers#' => 'http://customers-svc',
'#^/api/catalog#' => 'http://catalog-svc',
];
function resolveUpstream(string $path, array $routes): ?string {
foreach ($routes as $pattern => $upstream) {
if (preg_match($pattern, $path)) {
return $upstream . $path;
}
}
return null; // 404 at the gateway
}
echo resolveUpstream('/api/orders/42', $routes), "\n";Centralização da autenticação
Valide o chamador uma vez na porta de entrada e, depois, encaminhe uma identidade confiável para os serviços seguintes, para que cada serviço não precise verificar novamente o token bruto. A porta de entrada verifica a assinatura e a expiração do JWT e injeta cabeçalhos como X-User-Id na requisição interna (por uma rede confiável).
<?php
function authenticate(string $authHeader): ?array {
if (!str_starts_with($authHeader, 'Bearer ')) return null;
$jwt = substr($authHeader, 7);
$claims = verifyJwt($jwt); // signature + exp check
if ($claims === null) return null;
// Forward minimal trusted identity to internal services
return ['X-User-Id' => $claims['sub'], 'X-Scopes' => implode(',', $claims['scopes'])];
}
function verifyJwt(string $j): ?array { return ['sub' => 'u-7', 'scopes' => ['orders:read']]; }
print_r(authenticate('Bearer abc.def.ghi'));Agregação de respostas
Uma tela móvel pode precisar de dados de pedido, cliente e catálogo. Em vez de fazer o cliente iniciar três chamadas, a porta de entrada distribui as chamadas, aguarda e combina os resultados. Para manter isso rápido, faça as chamadas aos serviços de destino de forma concorrente (promessas do Guzzle / curl_multi), em vez de sequencialmente.
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Promise\Utils;
$http = new Client(['timeout' => 2.0]);
$promises = [
'order' => $http->getAsync('http://orders-svc/orders/42'),
'customer' => $http->getAsync('http://customers-svc/customers/7'),
'catalog' => $http->getAsync('http://catalog-svc/items?order=42'),
];
$results = Utils::settle($promises)->wait(); // run in parallel
// merge the fulfilled bodies into one response for the clientServiços de retaguarda para interfaces
Uma porta de entrada genérica muitas vezes não consegue atender igualmente bem a uma aplicação web, uma aplicação móvel e parceiros — cada um precisa de agregações e formatos de dados diferentes. O padrão de retaguarda por interface (BFF) fornece a cada tipo de cliente sua própria porta de entrada enxuta, adaptada às suas necessidades, enquanto os serviços compartilhados permanecem genéricos.
Isso evita uma porta de entrada monolítica e permite que cada equipe de cliente avance de forma independente.
O problema da descoberta
Em um ambiente dinâmico, as instâncias entram e saem, e seus IPs mudam. Codificar http://10.0.3.14:8080 diretamente é frágil. A descoberta de serviços mantém um registro ativo de "quais instâncias saudáveis do serviço X existem neste momento", para que os chamadores resolvam um nome lógico para um endereço real no momento da chamada.
Descoberta no cliente versus no servidor
Há dois modelos:
- No cliente — o chamador consulta um registro (Consul, etcd), escolhe uma instância por conta própria e faz seu próprio balanceamento de carga.
- No servidor — o chamador acessa um endereço virtual estável (um balanceador de carga / Kubernetes Service), que resolve o endereço e faz o balanceamento por ele.
No Kubernetes, geralmente você obtém a descoberta no servidor gratuitamente: chame http://customers-svc e o DNS do cluster + Service cuidam do restante. Fora do k8s, registros no estilo Consul são comuns.
Consultando um registro
Com a descoberta no cliente, o chamador em PHP solicita ao registro as instâncias saudáveis e escolhe uma. O registro só retorna instâncias que passam nas verificações de integridade, portanto os nós indisponíveis são excluídos automaticamente.
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
function discover(Client $http, string $service): string {
// Consul: only passing-health instances
$res = $http->get("http://consul:8500/v1/health/service/$service?passing=true");
$nodes = json_decode((string) $res->getBody(), true);
if (!$nodes) throw new \RuntimeException("No healthy $service");
$pick = $nodes[array_rand($nodes)]['Service']; // simple LB
return "http://{$pick['Address']}:{$pick['Port']}";
}Verificações de integridade e registro
A descoberta só é tão boa quanto os dados de integridade que recebe. Cada serviço expõe um ponto de acesso /health que verifica suas dependências reais (banco de dados, cache) e registra a si próprio (ou é registrado pela plataforma) na inicialização. O registro consulta esse ponto de acesso e remove as instâncias que falham.
Faça a verificação de integridade ser significativa: retornar 200 enquanto o banco de dados está indisponível é pior do que inútil — isso direciona tráfego para um nó defeituoso.
<?php
// GET /health
function health(PDO $db, Redis $cache): array {
$checks = [
'db' => safe(fn() => $db->query('SELECT 1') !== false),
'cache' => safe(fn() => $cache->ping() === '+PONG'),
];
$ok = !in_array(false, $checks, true);
http_response_code($ok ? 200 : 503);
return ['status' => $ok ? 'pass' : 'fail', 'checks' => $checks];
}
function safe(callable $c): bool { try { return (bool) $c(); } catch (\Throwable) { return false; } }Vivacidade versus prontidão
Um único ponto de acesso de integridade não basta — diferencie duas perguntas:
- Vivacidade: "o processo está ativo?" Se falhar, o orquestrador reinicia o contêiner. Mantenha essa verificação barata e sem dependências, ou um banco de dados instável provocará reinicializações desnecessárias.
- Prontidão: "o processo pode atender ao tráfego agora?" Se falhar, o tráfego é retido, mas o processo continua em execução (por exemplo, enquanto aquece um cache ou o banco de dados está temporariamente inacessível).
Confundir as duas causa ciclos de reinicialização ou roteamento para nós que ainda não estão prontos.
<?php
// GET /livez - is the process itself healthy? (no external deps)
function livez(): void { http_response_code(200); echo 'alive'; }
// GET /readyz - should we receive traffic? (checks dependencies)
function readyz(PDO $db): void {
try { $db->query('SELECT 1'); http_response_code(200); echo 'ready'; }
catch (\Throwable) { http_response_code(503); echo 'not ready'; }
}Verificação rápida
Reduzir as viagens de ida e volta do cliente.
Recapitulação
Roteamento e localização de serviços:
- Uma porta de entrada da API centraliza roteamento, autenticação, limitação de taxa, TLS e agregação.
- Agregue de forma concorrente; use BFFs quando as necessidades dos clientes divergirem.
- A descoberta de serviços resolve nomes lógicos para instâncias ativas e saudáveis.
- Descoberta no cliente (consultar um registro) versus no servidor (LB estável / k8s Service).
- Verificações de integridade significativas mantêm o tráfego longe de nós defeituosos.
A seguir: como manter todas essas chamadas resilientes quando partes inevitavelmente falharem.
Perguntas Frequentes
A aula “Gateways de API e descoberta de serviços” é grátis?
Sim — o texto completo de “Gateways de API e descoberta de serviços” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de PHP Academy, atualize para CoddyKit PRO. O curso de PHP Academy inclui 4 aulas no total.
O que vou aprender em “Gateways de API e descoberta de serviços”?
Encaminhe, agregue e localize serviços dinamicamente. Você pratica PHP Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar PHP Academy?
Nenhuma experiência prévia é necessária. PHP Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Gateways de API e descoberta de serviços”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de PHP Academy?
Sim. Cada aula de PHP Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Do monólito aos microsserviços
- Comunicação entre serviços: REST e gRPC
- Gateways de API e descoberta de serviços
- Resiliência: disjuntores e novas tentativas