J'ai un site Web sans serveur sur AWS S3. Mais S3 a une limitation que je veux surmonter: il ne me permet pas d'avoir des URL conviviales.
Par exemple, je voudrais remplacer l'URL:
www.mywebsite.com/user.html?login=daniel
Avec cette URL conviviale:
www.mywebsite.com/user/daniel
Je voudrais donc savoir si je peux utiliser Lambda avec API Gateway pour y parvenir.
Mon idée est:
API Gateway ---> Fonction Lambda ---> récupérer la ressource S3
La passerelle API recevra N'IMPORTE QUELLE requête et transmettra des informations à une fonction Lambda, qui traitera une logique à l'aide de l'URL de la requête (y compris peut-être une requête de base de données), puis récupérera la ressource de S3.
Je sais que l'objectif principal d'AWS API Gateway est d'être une passerelle vers les API REST, mais pouvons-nous également l'utiliser comme proxy pour un site Web entier?
3 Réponses :
La bonne option peut être d'utiliser CloudFront comme proxy inverse, vous pouvez utiliser la requête de réponse Viewer / Origin pour déclencher lambda et récupérer la ressource depuis S3.
https://docs.aws.amazon.com /AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html
Lambda @ Edge me permet-il de faire tout ce que je peux faire dans Lambda normal? Y compris faire des requêtes aux tables DynamoDB?
Oui, il peut accéder aux tables DynamoDB, mais la fonction du déclencheur lambda @ edge en fonction de la région où votre demande a atterri, par exemple si vous vous êtes connecté à l'emplacement périphérique CloudFront aux États-Unis (supposons que us-east-1) mais que votre table se trouve dans us-west -2, le lambda dans us-east-1 déclencherait la table dans us-west-2, ce qui pourrait provoquer une latence, etc. (la fonction lambda @ edge est répliquée automatiquement dans toutes les régions)
Mais pourquoi avons-nous besoin de CloudfFront + Lambda @ Edge? Lambda n'est-il pas suffisant pour la réécriture d'URL? Pourquoi ai-je besoin de CDN?
Un exemple simple serait d'écrire la fonction de demande / réponse d'origine lambda @, puis d'utiliser la mise en cache CDN pour servir la réponse redirigée, cela réduirait l'invocation lambda par rapport à APIGW où chaque fois que les déclencheurs lambda et le coût peuvent être réduits.
Donc, peut-être que le mieux serait de ne mettre en cache que les fichiers statiques (images, css, Javascript ...) en créant un sous-domaine séparé pour eux ( static.mywebsite.com ). Et le contenu dynamique ( mywebsite.com ) serait accessible directement avec API Gateway, évitant ainsi des coûts supplémentaires avec CloudFront et Lambda @ Edge?
Un bon pari serait d'utiliser CloudFront et Lambda @ Edge.
Lambda @ Edge vous permet d'exécuter la fonction Lambda à l'emplacement périphérique du réseau CDN CloudFront.
CloudFront vous offre la possibilité de vous connecter à divers événements au cours de son cycle de vie et d'appliquer une logique.
Cet article semble décrire quelque chose de similaire à ce dont vous parlez.
Lambda @ Edge me permet-il de faire tout ce que je peux faire dans Lambda normal? Y compris faire des requêtes aux tables DynamoDB?
Oui, vous pouvez faire tout cela.
Mais pourquoi avons-nous besoin de CloudfFront + Lambda @ Edge? Lambda n'est-il pas suffisant pour la réécriture d'URL? Pourquoi ai-je besoin de CDN?
De plus, le coût Lambda @ Edge est 3 fois plus cher que Lambda. Lambda coûte 0,20 USD par million de requêtes, tandis que Lambda @ Edge coûte 0,60 USD par million de requêtes
Il est possible d'utiliser API Gateway comme proxy inverse pour un site Web S3.
J'ai pu effectuer les étapes suivantes ci-dessous:
Dans le Lambda, nous pouvons acheminer les requêtes:
'use strict'; const AWS = require('aws-sdk'); const s3 = new AWS.S3(); const myBucket = 'myBucket'; exports.handler = async (event) => { var responseBody = ""; if (event.path=="/") { responseBody = "<h1>My Landing Page</h1>"; responseBody += "<a href='/xpto'>link to another page</a>"; return buildResponse(200, responseBody); } if (event.path=="/xpto") { responseBody = "<h1>Another Page</h1>"; responseBody += "<a href='/'>home</a>"; return buildResponse(200, responseBody); } if (event.path=="/my-s3-resource") { var params = { Bucket: myBucket, Key: 'path/to/my-s3-resource.html', }; const data = await s3.getObject(params).promise(); return buildResponse(200, data.Body.toString('utf-8')); } return buildResponse(404, '404 Error'); }; function buildResponse(statusCode, responseBody) { var response = { "isBase64Encoded": false, "statusCode": statusCode, "headers": { "Content-Type" : "text/html; charset=utf-8" }, "body": responseBody, }; return response; }
Quelle est votre ressource S3? Un SPA (Angular / React / Vue) ou autre chose?
SPA (AngularJS)