如何在同一个域中并行使用 AWS CloudFront 和 API Gateway?

如何在同一个域中并行使用 AWS CloudFront 和 API Gateway?

我将网站的静态资产放在 S3 上,并设置 CloudFront 来分发它们。这些资产本质上保存了用户对我网站上的任何 GET 请求所需的内容,即保存到现有路径,并带有错误捕获功能。

我还需要处理一些 POST 请求。表单提交、发送电子邮件、通知、与数据库交互。

如何为同一域同时设置 Lambda(或 API 网关)和 CloudFront,以便 CloudFront 处理 GET 请求,API 网关处理带有正文或 POST 请求的请求。或者我可以通过某种方式通过单个 URL 来完成吗?

答案1

我按照你提出的设计运行了多个 Web 应用程序,并且提取了戈法斯,一款教育性的 Go 和 Lambda 应用程序,用于分享技术。

您需要两个独立的域,例如www.gofaas.netS3 + CloudFront 和api.gofaas.netAPI 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);
    });

以下是一些设置指南:

使用 S3、CloudFront 和 ACM 的静态网站

使用 Lambda、API 网关、CORS 和 JWT 实现 API 安全

答案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/*

相关内容