Comment puis-je utiliser AWS CloudFront et API Gateway côte à côte pour le même domaine?

9

Je mets les actifs statiques de mon site Web sur S3 et je configure CloudFront pour les distribuer. Ceux-ci contiennent essentiellement le contenu dont les utilisateurs auraient besoin pour toute demande GET sur mon site, vers des chemins existants, c'est-à-dire avec un fourre-tout pour les erreurs.

J'ai également quelques requêtes POST à ​​gérer. Soumettre des formulaires, envoyer des e-mails, des notifications, interagir avec la base de données.

Comment puis-je configurer Lambda (ou API Gateway) côte à côte avec CloudFront pour le même domaine afin que CloudFront gère les demandes GET et API Gateway gère les demandes avec un corps ou des demandes POST. Ou puis-je le faire par URL individuelle d'une manière ou d'une autre?

Costa
la source

Réponses:

2

Je lance plusieurs applications Web exactement avec la conception que vous proposez et j'ai extrait des gofaas , une application pédagogique Go et Lambda, pour partager les techniques.

Vous avez besoin de deux domaines distincts, par exemple www.gofaas.netpour S3 + CloudFront et api.gofaas.netpour API Gateway + Lambda.

Ensuite, vous pouvez laisser votre site statique interagir avec l'API avec une configuration CORS API Gateway et du JavaScript:

fetch(`https://api.gofaas.net/work`, {
    method: "POST",
    mode: "cors",
    headers: {
        "Accept": "application/json",
        ...
    },
    body: JSON.stringify(...)
})
    .then(function(response) {
        return response.json();
    })
    .then(function (json) {
        // use response
    })
    .catch(function (err) {
        console.log("fetch error", err);
    });

Voici quelques guides pour configurer tout cela:

Sites Web statiques avec S3, CloudFront et ACM

Sécurité des API avec Lambda, API Gateway, CORS et JWT

Noah Zoschke
la source
Tester le site devient toujours intéressant ici. Il est difficile de répliquer l'infrastructure AWS localement afin de pouvoir effectuer des tests d'intégration localement. J'utilise un itinéraire au lieu d'un sous-domaine. Cela aide une partie des tests. Élimine également les défis CORS. Ensuite, API Gateway devient une origine pour CloudFront pour cette route.
Costa
6

Vous pouvez créer une fonction lambda, configurer une passerelle API, puis configurer CloudFront pour transférer certains chemins (par exemple / rest / *) vers la passerelle API, et servir tout le reste à partir d'un compartiment S3.

Voici une présentation complète montrant comment procéder: https://www.codeengine.com/articles/process-form-aws-api-gateway-lambda/

Grodriguez
la source
2

Du point de vue de la connexion, "quelque chose" doit répondre à vos demandes (GET, POST, PUT, tout). Tout d'abord, vous avez une connexion TCP et "quelque chose" doit s'assurer qu'il comprend la couche 7 et donne un sens aux octets que le client envoie. Ce n'est qu'à ce stade qu'il est possible de traiter les demandes GET différemment des demandes POST ou d'une URL à une autre URL. Donc, à la fin, vous avez besoin d'un service capable de comprendre et d'acheminer HTTP. Les services suivants sont capables de le faire: CloudFront ELB / ALB API Gateway (la limitation vient plus tard)

API Gateway utilise CloudFront en interne (sans vous donner la possibilité de configurer quoi que ce soit au niveau de CloudFront) - cela signifie qu'il n'y a aucun moyen d'exécuter CloudFront et API Gateway côte à côte, car à la fin cela signifierait que vous exécutez CloudFront avec CloudFront cote à cote.

CloudFront vous donne la possibilité de sélectionner différentes origines en fonction de modèles - mais vous ne pouvez sélectionner que S3 ou ELB / ALB comme origine - pas les fonctions Lambda (en plus de la fonctionnalité Lambda @ Edge).

ALB / ELB ne peut utiliser que des instances EC2 comme backend - pas de Lambda ou S3 ici.

Les seules façons dont je peux penser qui pourraient faire ce que vous voulez faire sont les suivantes:

  • Vous utilisez la passerelle API et acheminez un chemin d'accès "actif" spécifique vers une fonction Lambda qui fait une sorte de proxy inverse pour S3 (afin de canaliser les actifs statiques via lambda) - soyez conscient des coûts pour Lambda ici!
  • Vous pouvez faire de même, mais au lieu de canaliser l'actif via Lambda, générez simplement une URL signée dans Lambda et redirigez directement vers S3 pour la servir (cela pourrait être plus rentable)
  • Utiliser des sous-domaines différents pour vos actifs que le reste de votre application - c'est un modèle très courant car vous pouvez facilement vous répartir au niveau DNS et utiliser différents services pour les différents cas d'utilisation (CloudFront pour les actifs et API Gateway pour les non statiques) les pièces)

Mon appel serait donc la dernière option - mais cela signifie que vous devez pointer les clients / navigateurs vers un sous-domaine distinct pour tous les actifs statiques (ou pour toutes les demandes POST).

Il semble que vous souhaitiez jeter un œil à des technologies comme AngularJS ou React pour créer une application véritablement pilotée par API dans le navigateur. Avec cette approche, vous exécutez une véritable API qui gère toutes les demandes "dynamiques" avec une passerelle API et fournit l'application elle-même à partir de S3 en tant qu'actif statique. Peut-être que les regarder pourrait vous aider à trouver votre chemin - même si vous ne les utilisez pas, le modèle architectural sur la façon de construire des choses comme celle-ci est ce que vous demandez à mon humble avis.

Osterjour
la source
2

J'ai la même configuration. Les actifs statiques sur S3, les fonctions Lambda servies via la passerelle API, et ils partagent le même nom de domaine.

J'utilise une passerelle API qui utilise déjà CloudFront et expose certaines de ses fonctionnalités telles que la mise en cache. Ensuite, je configure les URI qui correspondent aux actifs statiques. Dans API Gateway, une ressource peut être une fonction Lambda, une fonction AWS, une maquette ou une autre URL. Je les fais pointer vers mes URL S3.

Les URI peuvent également être définis pour glober les sous-chemins, par exemple /assets/*.

Prathan Thananart
la source
La partie qui me pose problème est donc le déploiement de l'API. Il se déploie généralement sans le chemin d'accès principal, dans votre cas /assets/*. Je dois supprimer le déploiement, et cliquer avec le bouton droit sur le /assets/*chemin et déployer à partir de là.
Costa
1
Je devrais creuser dans les outils de ligne de commande et apprendre à créer et à modifier des api et des lambda à partir de là.
Costa