API-Gateways und Service Discovery
Dienste dynamisch weiterleiten, aggregieren und auffinden
API-Gateways und Service Discovery ist eine kostenlose PHP Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des PHP Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.
Gateways & Service Discovery
Wenn Sie ein Dutzend Services haben, treten zwei Probleme auf. Clients sollten weder die Adresse jedes einzelnen Services kennen noch fünf Services aufrufen müssen, um eine Ansicht zu rendern – das ist die Aufgabe des API-Gateways. Und Services, die hoch- oder herunterskalieren und ihre IPs ändern, brauchen eine Möglichkeit, einander zu finden – das ist Service Discovery.
Diese Lektion behandelt beides, mit PHP an der Gateway-Schicht.
Aufgaben eines API-Gateways
Ein API-Gateway ist ein einziger Einstiegspunkt vor Ihren Services. Typische Aufgaben:
- Routing von Anfragen an das richtige Backend.
- Querschnittsfunktionen: Authentifizierung, Rate Limiting, CORS und TLS-Terminierung.
- Aggregation: Mehrere Backend-Aufrufe zu einer Client-Antwort zusammenführen.
- Protokollübersetzung: Extern REST, intern gRPC.
So bleiben Clients einfach, und Richtlinien werden zentral verwaltet, statt sie in jedem Service zu duplizieren.
Routing am Gateway
Im Kern ordnet ein Gateway einen eingehenden Pfad einem Upstream-Service zu. Produktions-Gateways wie Kong, Traefik, Nginx und AWS API Gateway erledigen dies deklarativ, aber die Logik ist einfach genug, um sie in PHP zu veranschaulichen.
<?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";Authentifizierung zentralisieren
Validieren Sie den Aufrufer einmal am Gateway und leiten Sie anschließend eine vertrauenswürdige Identität an nachgelagerte Services weiter, damit jeder Service das ursprüngliche Token nicht erneut verifizieren muss. Das Gateway prüft die JWT-Signatur und das Ablaufdatum und fügt Header wie X-User-Id in die interne Anfrage ein (über ein vertrauenswürdiges Netzwerk).
<?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'));Antwortaggregation
Eine mobile Ansicht benötigt möglicherweise Bestell-, Kunden- und Katalogdaten. Statt den Client drei Aufrufe ausführen zu lassen, verteilt das Gateway die Anfragen, wartet und führt die Ergebnisse zusammen. Damit dies schnell bleibt, sollten Sie die Upstream-Aufrufe parallel ausführen (Guzzle promises / curl_multi) statt nacheinander.
<?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 clientBackends for Frontends
Ein allgemeines Gateway kann eine Webanwendung, eine mobile App und Partner oft nicht gleichermaßen gut bedienen – jeder Clienttyp benötigt andere Aggregationen und Payload-Strukturen. Das Muster Backend-for-Frontend (BFF) gibt jedem Clienttyp ein eigenes, schlankes Gateway, das auf seine Bedürfnisse zugeschnitten ist, während die gemeinsamen Services generisch bleiben.
So vermeiden Sie ein überladenes God-Gateway, und jedes Clientteam kann unabhängig arbeiten.
Das Discovery-Problem
In einer dynamischen Umgebung kommen Instanzen hinzu und verschwinden wieder, und ihre IPs ändern sich. Die Adresse http://10.0.3.14:8080 fest zu codieren, ist fragil. Service Discovery führt eine aktuelle Registry darüber, „welche gesunden Instanzen des Services X gerade existieren“, sodass Aufrufer einen logischen Namen zum Zeitpunkt des Aufrufs in eine echte Adresse auflösen können.
Clientseitige vs. serverseitige Service Discovery
Zwei Modelle:
- Clientseitig – der Aufrufer fragt eine Registry ab (Consul, etcd), wählt selbst eine Instanz aus und übernimmt das Load Balancing.
- Serverseitig – der Aufrufer verwendet eine stabile virtuelle Adresse (einen Load Balancer / Kubernetes Service), der die Auflösung und das Load Balancing übernimmt.
In Kubernetes erhalten Sie serverseitige Discovery normalerweise kostenlos: Rufen Sie http://customers-svc auf, und Cluster-DNS sowie Service erledigen den Rest. Außerhalb von k8s sind Registries nach dem Vorbild von Consul üblich.
Eine Registry abfragen
Bei clientseitiger Discovery fragt der PHP-Aufrufer die Registry nach gesunden Instanzen und wählt eine davon aus. Die Registry gibt nur Instanzen zurück, die die Health Checks bestehen, sodass ausgefallene Knoten automatisch ausgeschlossen werden.
<?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']}";
}Health Checks & Registrierung
Discovery ist nur so gut wie ihre Gesundheitsdaten. Jeder Service stellt einen /health-Endpunkt bereit, der seine tatsächlichen Abhängigkeiten (Datenbank, Cache) prüft, und registriert sich beim Start selbst (oder wird von der Plattform registriert). Die Registry ruft diesen Endpunkt regelmäßig auf und entfernt fehlschlagende Instanzen.
Gestalten Sie den Health Check aussagekräftig: 200 zurückzugeben, während die Datenbank nicht erreichbar ist, ist schlimmer als nutzlos – der Datenverkehr wird dadurch an einen defekten Knoten geleitet.
<?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; } }Liveness vs. Readiness
Ein einziger Health-Endpunkt reicht nicht aus – unterscheiden Sie zwei Fragen:
- Liveness: „Ist der Prozess aktiv?“ Bei einem Fehler startet der Orchestrator den Container neu. Halten Sie diese Prüfung kostengünstig und unabhängig von Abhängigkeiten, sonst löst eine instabile Datenbank sinnlose Neustarts aus.
- Readiness: „Kann der Prozess gerade Datenverkehr bedienen?“ Bei einem Fehler wird der Datenverkehr zurückgehalten, aber der Prozess läuft weiter (zum Beispiel beim Aufwärmen eines Caches oder wenn die Datenbank vorübergehend nicht erreichbar ist).
Wenn Sie beides vermischen, entstehen Neustartschleifen oder Datenverkehr wird an noch nicht bereite Knoten geleitet.
<?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'; }
}Kurzprüfung
Roundtrips des Clients reduzieren.
Zusammenfassung
Services routen und lokalisieren:
- Ein API-Gateway zentralisiert Routing, Authentifizierung, Rate Limiting, TLS und Aggregation.
- Aggregieren Sie parallel; verwenden Sie BFFs, wenn die Anforderungen der Clients auseinandergehen.
- Service Discovery löst logische Namen in aktive, gesunde Instanzen auf.
- Clientseitige Discovery (Registry abfragen) im Gegensatz zu serverseitiger Discovery (stabiler Load Balancer / k8s Service).
- Aussagekräftige Health Checks halten Datenverkehr von defekten Knoten fern.
Als Nächstes: Wie Sie all diese Aufrufe resilient halten, wenn Teile unweigerlich ausfallen.
Häufig gestellte Fragen
Ist die Lektion „API-Gateways und Service Discovery“ kostenlos?
Ja — der vollständige Text von „API-Gateways und Service Discovery“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des PHP Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „API-Gateways und Service Discovery“?
Dienste dynamisch weiterleiten, aggregieren und auffinden Du übst PHP Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um PHP Academy zu starten?
Keine Vorkenntnisse erforderlich. PHP Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „API-Gateways und Service Discovery“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser PHP Academy-Lektion Code schreiben und ausführen?
Ja. Jede PHP Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Vom Monolithen zu Microservices
- Servicekommunikation: REST und gRPC
- API-Gateways und Service Discovery
- Resilienz: Circuit Breaker und Retries