Как я могу использовать AWS CloudFront и API Gateway одновременно для одного домена?
Я размещаю эти статические ресурсы моего сайта на S3 и настраиваю CloudFront для их распространения. По сути, они содержат контент, который понадобится пользователям для любого запроса GET на моем сайте, к существующим путям, то есть с ловушкой для ошибок.
У меня также есть несколько запросов POST, которые мне нужно обработать. Форма подачи заявок, отправка электронных писем, уведомлений, взаимодействие с базой данных.
Как я могу настроить Lambda (или API-шлюз) рядом с CloudFront для того же домена, чтобы CloudFront обрабатывал запросы GET, а API-шлюз обрабатывал запросы с телом или запросами POST. Или я могу сделать это как-то по отдельному URL?
4 ответа
Я запускаю несколько веб-приложений именно с вашим предложенным дизайном и извлекаю gofaas, образовательное приложение Go и Lambda, чтобы поделиться этими методами.
Вам нужны два отдельных домена, например www.gofaas.net
для S3 + CloudFront и api.gofaas.net
для API Gateway + Lambda.
Затем вы можете позволить вашему статическому сайту взаимодействовать с API с помощью конфигурации API-интерфейса шлюза CORS и некоторого 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);
});
Вот несколько советов по настройке всего этого:
Вы можете создать лямбда-функцию, настроить шлюз API, а затем настроить CloudFront для пересылки определенных путей (например, /rest/*) к шлюзу API и обслуживать все остальное из корзины S3.
Вот полный обзор того, как это сделать: https://www.codeengine.com/articles/process-form-aws-api-gateway-lambda/
С точки зрения соединения "что-то" должно отвечать на ваши запросы (GET, POST, PUT, все). Прежде всего, у вас есть TCP-соединение, и "что-то" должно убедиться, что оно понимает уровень 7 и имеет смысл из байтов, которые отправляет клиент. Только на этом этапе можно обрабатывать запросы GET иначе, чем запросы POST или один URL-адрес, чем другой URL-адрес. Таким образом, в конце концов вам нужен сервис, который способен понимать и маршрутизировать HTTP. Следующие сервисы способны сделать это: CloudFront ELB/ALB API Gateway (ограничение наступит позже)
API Gateway использует CloudFront для внутреннего использования (не давая вам возможности фактически настроить что-либо на уровне CloudFront) - это означает, что нет способа запустить CloudFront и API Gateway параллельно, так как в конечном итоге это будет означать, что вы запустите CloudFront с CloudFront бок о бок.
CloudFront дает вам возможность выбирать различные источники на основе шаблонов - но вы можете выбрать только S3 или ELB/ALBs в качестве источника - не функции Lambda (помимо функциональности Lambda@Edge).
ALB / ELB может использовать только экземпляры EC2 в качестве бэкэнда - здесь нет лямбды или S3.
Я могу думать только о том, что может делать то, что вы хотите, это:
- Вы используете API-шлюз и маршрутизируете конкретный путь "актива" в функцию Lambda, которая выполняет функцию обратного прокси-сервера для S3 (так что передача статических активов через лямбду) - узнайте о затратах для Lambda здесь!
- Вы можете сделать то же самое, но вместо того, чтобы передавать ресурс через Lambda, просто сгенерируйте подписанный URL-адрес внутри Lambda и перенаправьте его непосредственно на S3 для обслуживания (может быть более экономичным)
- Using different subdomains for your assets than the rest of your application - this is a very common pattern as you can easily split out on the DNS level and use different services for the different use cases (CloudFront for assets and API Gateway for the non-static parts)
So my call would be the last option - but that means you need to point the clients/browsers to a separate subdomain for all static assets (or for all POST requests).
It sounds like you want to have a look at technologies like AngularJS or React to build a truly API-driven application in the browser. With this approach you're running a real API which is handling all the "dynamic" requests with an API Gateway and delivering the application itself from S3 as an static asset. Maybe looking at those might help you to find your way - even if you don't use them, the architectural pattern on how to build things like this is what you're asking for imho.
У меня такая же настройка. Статические активы на S3, функции Lambda обслуживаются через шлюз API, и они имеют одно и то же доменное имя.
Я использую API-шлюз, который уже использует CloudFront и предоставляет некоторые его функции, такие как кэширование. Затем я настраиваю URI, которые отображаются на статические ресурсы. В API Gateway ресурсом может быть функция Lambda, функция AWS, макет или другой URL-адрес. У меня есть они указывают на мои S3 URL.
URI также могут быть настроены для поиска подпутей, например: /assets/*
,