Avec la popularité du cloud computing et de l'architecture des microservices, la passerelle API est un élément indispensable du système de microservices et ses fonctions deviennent de plus en plus importantes. La passerelle API peut intercepter et transmettre toutes les demandes entrant et sortant du système et est responsable de la sécurité, du contrôle d'accès, du contrôle du trafic, de l'équilibrage de charge et d'autres fonctions.
Dans cet article, nous présenterons comment implémenter une passerelle API simple en utilisant PHP7.0 pour réaliser les fonctions suivantes :
Avant de commencer, assurez-vous d'avoir installé le logiciel suivant :
Étape 1 : Écrire une passerelle API de base
Tout d'abord, nous devons créer une passerelle API de base pour acheminer les requêtes vers les microservices. Nous utiliserons Symfony Routing Component pour gérer le routage.
Créez un nouveau fichier PHP, par exemple index.php, et ajoutez le code suivant :
require_once 'vendor/autoload.php'; use SymfonyComponentRoutingRouteCollection; use SymfonyComponentRoutingRoute; use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentRoutingMatcherUrlMatcher; use SymfonyComponentRoutingExceptionResourceNotFoundException; $routes = new RouteCollection(); $routes->add('hello', new Route('/hello/{name}', array( 'controller' => function ($request) { return new Response(sprintf("Hello, %s!", $request->attributes->get('name'))); } ))); $matcher = new UrlMatcher($routes, getRequest()); try { $request = Request::createFromGlobals(); $parameters = $matcher->matchRequest($request); $response = call_user_func($parameters['controller'], $request); } catch (ResourceNotFoundException $exception) { $response = new Response('Not Found', Response::HTTP_NOT_FOUND); } catch (Exception $exception) { $response = new Response('An error occurred', Response::HTTP_INTERNAL_SERVER_ERROR); } $response->send();
Dans ce code, on crée une route appelée "hello", cette route transmet la demande à une méthode de contrôleur anonyme. Lorsque cette route est traitée, elle renvoie "Bonjour, {name} !" dans la réponse, où {name} est le paramètre de route.
Nous utilisons les classes Request et Response de Symfony pour créer et envoyer des requêtes et des réponses HTTP. Le composant Routing de Symfony est responsable du routage des requêtes vers les routes correspondantes et de l'appel des méthodes de contrôleur correspondantes.
À ce stade, nous pouvons exécuter ce fichier, visiter http://localhost:8080/hello/world, et vous pourrez voir le résultat "Hello, world !".
Étape 2 : Ajouter la fonction de limitation actuelle
Nous espérons que la passerelle API pourra limiter chaque requête API afin de réduire les risques de surcharge côté serveur. Pour ce faire, nous pouvons utiliser Redis pour stocker les compteurs de limitation pour chaque API.
Tout d'abord, nous devons installer Predis à l'aide de Composer, qui est une bibliothèque client Redis en PHP :
composer require predis/predis
Ensuite, ajoutez le code suivant dans index.php pour que dans Check le compteur avant chaque requête de microservice :
use PredisClient; // ... $redis = new Client(); // Limit requests to 100 per minute per user. $maxRequests = 100; $timeWindow = 60; // seconds $ip = $_SERVER['REMOTE_ADDR']; $key = "ratelimit:{$ip}"; $currentRequests = $redis->incr($key); $redis->expire($key, $timeWindow); if ($currentRequests > $maxRequests) { $response = new Response('Rate limit exceeded', Response::HTTP_TOO_MANY_REQUESTS); $response->headers->set('Retry-After', $timeWindow); $response->send(); exit; }
Dans ce code, nous utilisons le client Predis pour nous connecter au serveur Redis et utilisons l'adresse IP de chaque requête comme nom de clé. Nous fixons une limite de 100 requêtes par minute et par utilisateur et utilisons la fonction Incr pour incrémenter le compteur.
Si la valeur actuelle du compteur dépasse la limite maximale, une réponse HTTP 429 "Too Many Requests" est renvoyée et l'en-tête "Retry-After" est défini pour informer le client quand essayer la requête encore.
Étape 3 : Ajouter des fonctions d'authentification et d'autorisation
Nous devons également ajouter des fonctions d'authentification et d'autorisation de base pour chaque requête API. Pour cela nous utiliserons le standard JSON Web Token (JWT).
Pour utiliser JWT, veuillez d'abord installer la bibliothèque firebase/php-jwt :
composer require firebase/php-jwt
Ensuite, ajoutez le code suivant dans index.php pour implémenter l'authentification et l'autorisation standard JWT :
use FirebaseJWTJWT; // ... $key = 'secret'; $token = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; if ($token) { try { $decoded = JWT::decode($token, $key, array('HS256')); $user_id = $decoded->sub; $roles = $decoded->roles; } catch (Exception $e) { $response = new Response('Invalid token', Response::HTTP_UNAUTHORIZED); $response->send(); exit; } // Check user roles and permissions here... } else { $response = new Response('Token required', Response::HTTP_UNAUTHORIZED); $response->send(); exit; }
Dans ce code, nous utilisons le token JWT extrait de l'en-tête HTTP pour identifier et authentifier la requête. Nous utilisons la bibliothèque JWT pour décoder le jeton et vérifier la signature et la validité. Si le jeton est valide, l'ID utilisateur et les informations sur le rôle en sont extraits et ses autorisations sont vérifiées. Si le jeton n'est pas valide, une réponse HTTP 401 « Non autorisé » est renvoyée.
Étape 4 : Ajouter une fonction de statistiques
Enfin, nous ajoutons une fonction de statistiques simple pour enregistrer l'utilisation de l'API. Pour ce faire, nous utiliserons Redis pour stocker des métriques telles que le nombre de requêtes et les temps de réponse.
Tout d'abord, nous devons installer l'extension phpredis :
sudo apt-get install php7.0-redis
Ensuite, ajoutez le code suivant dans index.php pour enregistrer les statistiques de chaque requête :
use PredisClient; // ... $redis = new Client(); $ip = $_SERVER['REMOTE_ADDR']; $key = "stats:{$ip}"; $now = time(); $timestamp = strtotime(date('Y-m-d H:i:00', $now)); $redis->zincrby($key, 1, $timestamp); $redis->expire($key, 3600);
Dans ce code, nous considérons le nombre de requêtes par adresse IP (c'est-à-dire par utilisateur) et augmentons la valeur du compteur de requêtes de 1 à l'aide de la commande ZINCRBY de Redis. Nous utilisons également la définition du délai d'expiration dans Redis pour supprimer les enregistrements expirés.
Étape 5 : Déployer API Gateway
Maintenant, nous avons ajouté des fonctions de base telles que le routage, les restrictions, l'authentification, l'autorisation et les statistiques à notre passerelle API. Nous pouvons le déployer à l'aide d'un serveur Web traditionnel comme Apache ou Nginx, ou utiliser le serveur PHP intégré pour les tests.
Tout d'abord, exécutez la commande suivante dans le terminal afin de démarrer le serveur PHP intégré et pointez-le vers notre fichier index.php :
php -S localhost:8080
Ensuite, nous pouvons Visitez http://localhost:8080/ et ajoutez des itinéraires tels que /hello/world dans le chemin de l'URL pour tester diverses fonctions de la passerelle API.
Summary
Dans cet article, nous utilisons PHP7.0 et diverses bibliothèques open source pour implémenter une passerelle API de base, et ajouter des restrictions, une authentification, une autorisation et des statistiques et d'autres fonctionnalités de base. fonctions. La passerelle API fait partie intégrante de l'architecture des microservices, ce qui peut nous aider à améliorer les performances, la sécurité et l'évolutivité.
En fait, il existe désormais de nombreuses solutions de passerelle API puissantes parmi lesquelles choisir, telles que Kong, Tyk, AWS API Gateway, etc., qui fournissent des fonctions et des intégrations plus avancées, telles que l'équilibrage de charge, la mise en cache, la sécurité, la surveillance. et gestion, etc
Cependant, il est toujours utile de savoir comment créer une passerelle API à l'aide de bibliothèques comme PHP et Symfony, et c'est une excellente option lorsque vous avez besoin de créer rapidement une passerelle API simple.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!