Skip to content

Module 3 — API Gateway, Reverse Proxy et Forward Proxy : la différence, testée en vrai

Bonne lecture et bon apprentissage ! Junior TSAFACK – 18/09/2026 Temps de lecture estimé : 16 minutes


Forward proxy, reverse proxy et API Gateway sont trois briques qui font, au niveau du paquet réseau, exactement la même chose : elles reçoivent une requête HTTP et la retransmettent vers une autre machine. C’est pour ça qu’on les confond. La différence n’est pas technique au sens du protocole — c’est une différence de position dans l’architecture et de qui elles servent :

  • Le forward proxy se place devant un groupe de clients et parle en leur nom au reste d’Internet. Il protège et contrôle le client.
  • Le reverse proxy se place devant un groupe de serveurs et reçoit les requêtes en leur nom. Il protège et contrôle le serveur.
  • L’API Gateway est un reverse proxy spécialisé pour les API : il fait tout ce qu’un reverse proxy fait, plus l’authentification, la limitation de débit, le routage vers plusieurs microservices et souvent la transformation des requêtes.

Le reste de ce module démontre ces trois comportements avec des instances réellement installées et interrogées dans l’environnement de ce cours (Nginx 1.24, Squid 6.14, HAProxy 2.8) — pas des extraits de documentation recopiés.

Forward proxy : Squid, au service du client

Section titled “Forward proxy : Squid, au service du client”

Une application Flask (catalogue-interne) tourne en local sur le port 5050. Un forward proxy Squid est configuré sur le port 3128. Le client choisit explicitement d’envoyer sa requête à travers ce proxy (curl -x http://127.0.0.1:3128 ...) — c’est la caractéristique clé d’un forward proxy : c’est le client qui le configure, pas le serveur cible qui l’impose.

squid.conf (extrait)
http_port 3128
acl localnet src 127.0.0.1
http_access allow localnet
http_access deny all

En changeant une seule ligne (http_access allow localnet → http_access deny localnet), Squid rejette la requête avant même de la transmettre :

$ curl -x http://127.0.0.1:3128 http://127.0.0.1:5050/api/produits
HTTP/1.1 403 Forbidden
Server: squid/6.14
X-Squid-Error: ERR_ACCESS_DENIED 0
Via: 1.1 vm (squid/6.14)

Le header Via: 1.1 vm (squid/6.14) est la preuve que c’est bien Squid qui a traité la requête, pas une réponse directe du backend.

Test 2 — ACL qui autorise, requête relayée avec succès

Section titled “Test 2 — ACL qui autorise, requête relayée avec succès”

Après avoir remis http_access allow localnet, la même requête traverse réellement Squid puis atteint le backend :

$ curl -x http://127.0.0.1:3128 http://127.0.0.1:5050/api/produits
HTTP/1.1 200 OK
Server: Werkzeug/3.1.8 Python/3.11.15
Via: 1.1 vm (squid/6.14)
{"produits":["clavier","souris","ecran"],"service":"catalogue-interne"}

Le journal d’accès Squid confirme les deux événements, dans l’ordre où ils se sont réellement produits :

$ cat access.log
... 127.0.0.1 TCP_DENIED/403 3390 GET http://127.0.0.1:5050/api/produits - HIER_NONE/-
... 127.0.0.1 TCP_MISS/200 303 GET http://127.0.0.1:5050/api/produits - HIER_DIRECT/127.0.0.1

Le client sait qu’il passe par un proxy (il le configure lui-même, via -x ou une variable http_proxy). Le serveur cible (127.0.0.1:5050), lui, ne sait rien de la politique d’accès qui vient d’être appliquée — pour lui, une requête est juste arrivée. C’est exactement le rôle d’un forward proxy en entreprise : contrôler et journaliser ce que les postes internes ont le droit d’atteindre à l’extérieur, filtrer les domaines interdits, mettre en cache des ressources fréquemment demandées, et anonymiser l’origine réelle du client vis-à-vis de la destination.

Reverse proxy : Nginx, au service du serveur

Section titled “Reverse proxy : Nginx, au service du serveur”

Le même backend Flask (127.0.0.1:5050) est maintenant placé derrière un reverse proxy Nginx sur le port 8081. Cette fois, c’est l’inverse : c’est l’opérateur du serveur qui configure le proxy, et le client n’a pas le choix — il ne peut pas décider de le contourner, puisque dans une vraie topologie réseau, le backend n’est routable que via ce proxy.

reverse-proxy.conf
events {}
http {
server {
listen 8081;
location / {
proxy_pass http://127.0.0.1:5050/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
add_header X-Proxy-By "nginx-reverse-proxy" always;
}
}
}
$ curl -D - http://127.0.0.1:8081/api/produits
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Content-Type: application/json
X-Proxy-By: nginx-reverse-proxy
{"produits":["clavier","souris","ecran"],"service":"catalogue-interne"}

Le client s’adresse à 127.0.0.1:8081 et n’a jamais eu besoin de connaître l’adresse 127.0.0.1:5050 du vrai backend — c’est exactement le miroir du forward proxy : là où le forward proxy cache le client au regard du serveur cible, le reverse proxy cache le serveur au regard du client. Le Module 1 de ce parcours a déjà montré, sur ce même principe, comment Nginx répartit la charge entre plusieurs backends et bascule automatiquement quand l’un d’eux tombe — c’est la responsabilité la plus classique d’un reverse proxy, mais pas la seule : il gère aussi la terminaison TLS, la compression, le cache de réponses, et fait écran de sécurité (le backend applicatif, potentiellement fragile, n’est jamais exposé directement à Internet).

API Gateway : Nginx configuré comme passerelle d’API

Section titled “API Gateway : Nginx configuré comme passerelle d’API”

Ce qu’une API Gateway ajoute par rapport à un simple reverse proxy

Section titled “Ce qu’une API Gateway ajoute par rapport à un simple reverse proxy”

Un reverse proxy « nu » fait suivre une requête vers un backend. Une API Gateway est un reverse proxy à qui on a ajouté des responsabilités propres au monde des API :

  1. Authentification centralisée — vérifier une clé API, un JWT ou un token OAuth avant que la requête n’atteigne un microservice, pour que chaque microservice n’ait pas à réimplémenter cette vérification.
  2. Routage par chemin vers plusieurs microservices distincts — un point d’entrée unique (une seule URL publique) qui redistribue en interne vers N services indépendants.
  3. Limitation de débit (rate limiting) par client, pour protéger les backends contre un usage abusif.
  4. Souvent aussi : transformation de requêtes/réponses, agrégation de plusieurs appels, observabilité centralisée (métriques, traces) sur tout le trafic API.

Le montage : deux microservices, une seule porte d’entrée

Section titled “Le montage : deux microservices, une seule porte d’entrée”

Deux applications Flask indépendantes :

  • catalogue-interne sur 127.0.0.1:5050 (exposant /api/produits)
  • commandes sur 127.0.0.1:5051 (exposant /commandes)

Et une API Gateway Nginx sur le port 8082 qui centralise l’authentification par clé API, le routage, et la limitation de débit :

gateway.conf
events {}
http {
limit_req_zone $http_x_api_key zone=par_client:10m rate=2r/s;
map $http_x_api_key $cle_valide {
default 0;
"cle-client-A" 1;
}
server {
listen 8082;
location /produits {
if ($cle_valide = 0) { return 401; }
limit_req zone=par_client burst=2 nodelay;
rewrite ^/produits(.*)$ /api/produits$1 break;
proxy_pass http://127.0.0.1:5050;
add_header X-Gateway "api-gateway-nginx" always;
add_header X-Route "service-catalogue" always;
}
location /commandes {
if ($cle_valide = 0) { return 401; }
limit_req zone=par_client burst=2 nodelay;
proxy_pass http://127.0.0.1:5051;
add_header X-Gateway "api-gateway-nginx" always;
add_header X-Route "service-commandes" always;
}
}
}

Test 1 — sans clé API, ou avec une clé invalide : refusé avant d’atteindre un microservice

Section titled “Test 1 — sans clé API, ou avec une clé invalide : refusé avant d’atteindre un microservice”
$ curl -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:8082/produits
HTTP 401
$ curl -o /dev/null -w "HTTP %{http_code}\n" -H "X-Api-Key: cle-invalide" http://127.0.0.1:8082/produits
HTTP 401

Ni catalogue-interne ni commandes n’ont reçu la moindre requête dans ce test — la gateway a coupé court avant de les solliciter.

Test 2 — avec la bonne clé, routage vers deux microservices différents

Section titled “Test 2 — avec la bonne clé, routage vers deux microservices différents”
$ curl -D - -H "X-Api-Key: cle-client-A" http://127.0.0.1:8082/produits
HTTP/1.1 200 OK
X-Gateway: api-gateway-nginx
X-Route: service-catalogue
{"produits":["clavier","souris","ecran"],"service":"catalogue-interne"}
$ curl -D - -H "X-Api-Key: cle-client-A" http://127.0.0.1:8082/commandes
HTTP/1.1 200 OK
X-Gateway: api-gateway-nginx
X-Route: service-commandes
{"commandes":[{"id":1,"statut":"expediee"}],"service":"commandes"}

Même point d’entrée (8082), même clé — mais deux backends complètement distincts (5050 et 5051) répondent selon le chemin appelé. Le client n’a jamais eu besoin de connaître l’existence de deux services séparés.

Test 3 — limitation de débit, en conditions réelles

Section titled “Test 3 — limitation de débit, en conditions réelles”

La zone limit_req_zone autorise 2 requêtes/seconde par clé API, avec une rafale (burst) de 2. Six requêtes envoyées le plus vite possible, avec la même clé :

Requête 1 -> HTTP 200
Requête 2 -> HTTP 200
Requête 3 -> HTTP 200
Requête 4 -> HTTP 503
Requête 5 -> HTTP 503
Requête 6 -> HTTP 503

Les 3 premières passent (le débit nominal plus la rafale absorbée), puis Nginx renvoie 503 sans même solliciter le backend — la protection contre les abus a bien lieu au niveau de la gateway, pas dans le code de chaque microservice.

L’API Gateway a fait, dans ce seul montage, ce qu’un reverse proxy classique ne fait pas nativement : elle a authentifié la requête, l’a routée vers l’un de deux services indépendants selon le chemin, et a limité le débit par client — trois responsabilités transversales retirées des microservices eux-mêmes et centralisées à la frontière.

Critère Forward proxy Reverse proxy API Gateway
Se place devant Les clients Les serveurs Les serveurs (API)
Configuré par Le client (ou son admin réseau) L’opérateur du service L’opérateur du service
Le client sait-il qu’il l’utilise ? Oui, explicitement Non, transparent Non, transparent
Ce qu’il cache L’identité/l’adresse du client L’identité/la topologie du serveur La topologie des microservices
Cas d’usage typique Filtrage web d’entreprise, anonymisation, cache sortant Répartition de charge, TLS, cache entrant Auth centralisée, rate limiting, agrégation d’API
Exemple testé dans ce module Squid (ACL client) Nginx (masque un backend) Nginx (auth + routage + rate limit)
Techno Type principal Points forts Limites Licence
Nginx Reverse proxy / LB / (gateway basique via modules) Très répandu, léger, excellente doc, sert aussi de serveur web statique Configuration déclarative peu flexible pour une logique métier complexe ; le vrai rate limiting/JWT avancé demande souvent des modules tiers ou OpenResty (Lua) BSD (gratuit)
HAProxy Reverse proxy / Load balancer Référence historique du LB haute performance, algorithmes d’équilibrage très riches, observabilité fine (page de stats intégrée), excellent sous forte charge Pas conçu pour la logique applicative niveau API (pas nativement JWT/OAuth) ; configuration orientée réseau plus que « API-first » GPL/Open-source (+ version Enterprise payante)
Envoy Proxy L4/L7 moderne, brique de service mesh Observabilité de pointe (métriques, traces natives), conçu pour le cloud-native et Kubernetes, base d’Istio Configuration très riche mais complexe à opérer seul (xDS, gRPC) — rarement utilisé “nu”, plutôt via Istio/Contour Apache 2.0 (gratuit)
Traefik Reverse proxy / API Gateway cloud-native Auto-découverte des services (Docker, Kubernetes) sans redémarrage, dashboard intégré, Let’s Encrypt automatique Écosystème de middlewares moins profond que Kong pour la gestion d’API métier (quotas avancés, monétisation) MIT (+ version Enterprise)
Kong API Gateway dédiée Conçu spécifiquement pour les API (auth, quotas, plugins, portail développeur), écosystème de plugins très large Empreinte plus lourde (base de données ou mode déclaratif à gérer), courbe d’apprentissage plus haute Apache 2.0 (+ Enterprise)
Apache APISIX API Gateway dédiée Architecture plugin très performante (basée sur Nginx/OpenResty + etcd), riche en fonctionnalités API (gRPC, gRPC-Web, plugins natifs) Communauté plus petite que Kong/Nginx, etcd ajoute une dépendance opérationnelle Apache 2.0 (gratuit)
AWS API Gateway API Gateway managée (cloud) Zéro infrastructure à gérer, intégration native Lambda/IAM/Cognito, scaling automatique Verrouillage fournisseur (vendor lock-in), coût à la requête qui peut grimper à fort volume, latence additionnelle par rapport à un gateway auto-hébergé Propriétaire, payant à l’usage
Squid Forward proxy Le forward proxy open-source de référence depuis des décennies, cache HTTP mature, ACL très granulaires (testé dans ce module) Pensé pour le trafic sortant client → Internet, pas pour exposer des services GPL (gratuit)
Tinyproxy Forward proxy léger Empreinte mémoire minimale, configuration très simple Beaucoup moins de fonctionnalités que Squid (pas de cache disque avancé, ACL plus basiques) GPL (gratuit)

Il n’y a pas une seule bonne réponse indépendante du contexte — mais un compromis se dégage selon le besoin réel :

  • Pour un simple reverse proxy / load balancer devant une application classique (le cas le plus fréquent en PME/ETI) : Nginx reste le meilleur compromis. Il est gratuit, extrêmement documenté, léger en ressources, et couvre 90 % des besoins (TLS, cache, répartition de charge, headers de sécurité) avec une configuration simple à auditer — comme démontré dans ce module et dans le Module 1. HAProxy reste préférable si la priorité absolue est la performance de répartition de charge à très haut débit avec des algorithmes fins (least-connections pondéré, sticky sessions avancées) et une observabilité réseau poussée.
  • Pour une vraie API Gateway avec logique métier (authentification OAuth/JWT native, quotas par client, portail développeur, agrégation de plusieurs microservices) : Kong est le meilleur compromis dans la plupart des cas — il est open-source, bâti sur Nginx (donc performant et déjà connu de l’équipe), et son système de plugins couvre l’essentiel sans réinventer la roue. Traefik devient le meilleur choix si l’environnement est déjà conteneurisé (Docker/Kubernetes) et que la priorité est l’auto-découverte des services sans redéploiement manuel de configuration.
  • Pour un environnement déjà entièrement sur AWS, où l’équipe ne veut gérer aucune infrastructure de gateway : AWS API Gateway est le meilleur compromis malgré le vendor lock-in, car le coût opérationnel économisé (pas de serveur à patcher, à scaler, à surveiller) dépasse souvent le surcoût à la requête pour des volumes modérés.
  • Pour un forward proxy d’entreprise (filtrage et contrôle du trafic sortant des postes de travail) : Squid reste le standard le plus robuste et le plus testé en production, comme démontré plus haut avec les ACL.

Recommandation générale pour ce parcours : démarrer avec Nginx comme reverse proxy/gateway de base (déjà maîtrisé grâce aux modules précédents), puis migrer vers Kong seulement si des besoins spécifiquement « API management » apparaissent (quotas commerciaux, portail développeur, fédération d’authentification) — migrer trop tôt vers une gateway dédiée ajoute de la complexité opérationnelle avant qu’elle ne soit réellement nécessaire.

Les tests ci-dessus utilisent une clé API statique en clair (map Nginx) pour rester lisibles pédagogiquement — une vraie API Gateway en production valide un JWT signé (voir le cours JWT de ce parcours) ou un token OAuth 2.0 (voir le cours OAuth) plutôt qu’une simple correspondance de chaîne. De même, la limitation de débit testée ici est locale à une seule instance Nginx — en production multi-instances, elle doit s’appuyer sur un compteur partagé (Redis) pour rester cohérente entre plusieurs répliques de la gateway.

Réseaux cloud et Kubernetes : Services, Ingress et concepts réseau