我将网站的静态资产放在 S3 上,并设置 CloudFront 来分发它们。这些资产本质上保存了用户对我网站上的任何 GET 请求所需的内容,即保存到现有路径,并带有错误捕获功能。
我还需要处理一些 POST 请求。表单提交、发送电子邮件、通知、与数据库交互。
如何为同一域同时设置 Lambda(或 API 网关)和 CloudFront,以便 CloudFront 处理 GET 请求,API 网关处理带有正文或 POST 请求的请求。或者我可以通过某种方式通过单个 URL 来完成吗?
答案1
我按照你提出的设计运行了多个 Web 应用程序,并且提取了戈法斯,一款教育性的 Go 和 Lambda 应用程序,用于分享技术。
您需要两个独立的域,例如www.gofaas.net
S3 + CloudFront 和api.gofaas.net
API Gateway + Lambda。
然后,您可以使用 API 网关 CORS 配置和一些 JavaScript 让您的静态站点与 API 交互:
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);
});
以下是一些设置指南:
答案2
您可以创建一个 lambda 函数,设置 API 网关,然后配置 CloudFront 以将某些路径(例如 /rest/*)转发到 API 网关,并从 S3 存储桶提供其他所有内容。
以下是完整的演示,展示如何执行此操作:https://www.codeengine.com/articles/process-form-aws-api-gateway-lambda/
答案3
从连接的角度来看,“某物”需要回答您的请求(GET、POST、PUT,一切)。首先,您有一个 TCP 连接,“某物”需要确保它理解第 7 层并理解客户端发送的字节。只有此时,才有可能以不同于 POST 请求的方式处理 GET 请求,或以不同于另一个 URL 的方式处理一个 URL。因此,最终您需要一种能够理解和路由 HTTP 的服务。以下服务能够做到这一点:CloudFront ELB/ALB API 网关(限制稍后公布)
API Gateway 在内部使用 CloudFront(不让您有机会在 CloudFront 级别实际配置任何内容) - 这意味着无法并行运行 CloudFront 和 API Gateway,因为最终这意味着您并行运行 CloudFront 和 CloudFront。
CloudFront 让您有机会根据模式选择不同的来源 - 但您只能选择 S3 或 ELB/ALB 作为来源 - 而不是 Lambda 函数(Lambda@Edge 功能除外)。
ALB/ELB 只能使用 EC2 实例作为后端 - 这里没有 Lambda 或 S3。
我能想到的唯一可以实现你想要做的事情的方法是:
- 您使用 API 网关并将特定的“资产”路径路由到 Lambda 函数,该函数对 S3 起到一种反向代理的作用(因此通过 lambda 传输静态资产) - 请注意此处 Lambda 的成本!
- 您可以做同样的事情,但不是通过 Lambda 传输资产,而是在 Lambda 中生成一个签名的 URL,然后直接重定向到 S3 进行服务(可能更具成本效益)
- 为您的资产使用与应用程序其余部分不同的子域 - 这是一种非常常见的模式,因为您可以轻松地在 DNS 级别进行拆分,并针对不同的用例使用不同的服务(用于资产的 CloudFront 和非静态部分的 API 网关)
所以我的呼叫将是最后一个选项 - 但这意味着您需要将客户端/浏览器指向所有静态资产(或所有 POST 请求)的单独子域。
听起来你想看看像 AngularJS 或 React 这样的技术,以便在浏览器中构建一个真正由 API 驱动的应用程序。通过这种方法,你将运行一个真正的 API,它使用 API 网关处理所有“动态”请求,并将应用程序本身作为静态资产从 S3 交付。也许看看这些可能会帮助你找到自己的方法——即使你不使用它们,在我看来,如何构建这样的东西的架构模式正是你所要求的。
答案4
我有相同的设置。S3 上的静态资产、通过 API 网关提供的 Lambda 函数,它们共享相同的域名。
我使用 API 网关,它已经使用了 CloudFront 并公开了它的一些功能,例如缓存。然后我配置映射到静态资产的 URI。在 API 网关中,资源可以是 Lambda 函数、AWS 函数、模拟或其他 URL。我让它们指向我的 S3 URL。
URI 也可以设置为子路径。例如/assets/*
。