Как я могу использовать AWS CloudFront и API Gateway одновременно для одного домена?

9

Я размещаю эти статические ресурсы моего сайта на S3 и настраиваю CloudFront для их распространения. По сути, они содержат контент, который понадобится пользователям для любого запроса GET на моем сайте, к существующим путям, то есть с ловушкой для ошибок.

У меня также есть несколько запросов POST, которые мне нужно обработать. Форма подачи заявок, отправка электронных писем, уведомлений, взаимодействие с базой данных.

Как я могу настроить Lambda (или API-шлюз) рядом с CloudFront для того же домена, чтобы CloudFront обрабатывал запросы GET, а API-шлюз обрабатывал запросы с телом или запросами POST. Или я могу сделать это как-то по отдельному URL?

ребро
источник

Ответы:

2

Я запускаю несколько веб-приложений именно с вашим предложенным дизайном и извлекаю 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);
    });

Вот несколько советов по настройке всего этого:

Статические сайты с S3, CloudFront и ACM

API-безопасность с использованием лямбды, API-шлюза, CORS и JWT

Ной Зошке
источник
Тестирование сайта всегда становится здесь интересным. Локально реплицировать инфраструктуру AWS сложно, чтобы можно было проводить интеграционные тесты локально. Я использую маршрут вместо поддоменов. Это помогает в части тестирования. Также устраняет проблемы с CORS. Затем API Gateway становится источником для CloudFront для этого маршрута.
Коста
6

Вы можете создать лямбда-функцию, настроить шлюз API, а затем настроить CloudFront для пересылки определенных путей (например, / rest / *) к шлюзу API и обслуживать все остальное из корзины S3.

Вот полный обзор того, как это сделать: https://www.codeengine.com/articles/process-form-aws-api-gateway-lambda/

Grodriguez
источник
2

С точки зрения соединения «что-то» должно отвечать на ваши запросы (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 / ALB в качестве источника, а не функции Lambda (помимо функциональности Lambda @ Edge).

ALB / ELB может использовать только экземпляры EC2 в качестве бэкэнда - здесь нет лямбды или S3.

Единственное, что я могу придумать, что может сделать то, что вы хотите сделать, это:

  • Вы используете API-шлюз и маршрутизируете конкретный путь «актива» в функцию Lambda, которая выполняет роль обратного прокси-сервера для S3 (так что передача статических активов через лямбду) - узнайте о затратах для Lambda здесь!
  • Вы можете сделать то же самое, но вместо того, чтобы передавать ресурс через Lambda, просто сгенерируйте подписанный URL-адрес внутри Lambda и перенаправьте напрямую на S3 для обслуживания (может быть более экономичным)
  • Использование других поддоменов для ваших активов, чем для остальной части вашего приложения - это очень распространенный шаблон, так как вы можете легко разделить на уровне DNS и использовать разные сервисы для разных вариантов использования (CloudFront для активов и API Gateway для нестатических части)

Поэтому мой вызов будет последним вариантом, но это означает, что вам нужно указать клиентам / браузерам отдельный поддомен для всех статических активов (или для всех запросов POST).

Звучит так, будто вы хотите взглянуть на такие технологии, как AngularJS или React, чтобы создать в браузере действительно управляемое API-приложение. При таком подходе вы запускаете настоящий API, который обрабатывает все «динамические» запросы со шлюзом API и доставляет само приложение из S3 в качестве статического ресурса. Возможно, просмотр этих может помочь вам найти свой путь - даже если вы их не используете, архитектурный паттерн о том, как создавать такие вещи, - это то, что вы просите imho.

Osterjour
источник
2

У меня такая же настройка. Статические активы на S3, функции Lambda обслуживаются через шлюз API, и они имеют одно и то же доменное имя.

Я использую шлюз API, который уже использует CloudFront и предоставляет некоторые его функции, такие как кэширование. Затем я настраиваю URI, которые отображаются на статические ресурсы. В API Gateway ресурсом может быть функция Lambda, функция AWS, макет или другой URL-адрес. У меня есть они указывают на мои S3 URL.

URI также могут быть настроены для поиска подпутей, например /assets/*.

Пратан Тананарт
источник
Поэтому часть, которая доставляет мне неприятности, - это развертывание API. В вашем случае он обычно развертывается без начального пути /assets/*. Я должен удалить развертывание, щелкнуть правой кнопкой мыши на /assets/*пути и развернуть оттуда.
Коста
1
Я должен покопаться в инструментах командной строки и научиться создавать и редактировать API и лямбда оттуда.
Коста