Зачем нужен API Gateway
API Gateway -- это "входная дверь" для вашего API. Он принимает HTTP-запросы от клиентов, маршрутизирует их к serverless-функциям и возвращает ответы. Без API Gateway вам пришлось бы самостоятельно реализовывать маршрутизацию, аутентификацию, rate limiting и CORS.
Функции API Gateway
| Функция | Описание |
|---|---|
| Маршрутизация | Направляет GET /count к нужной Lambda |
| CORS | Обрабатывает Cross-Origin запросы |
| Throttling | Ограничивает количество запросов |
| Аутентификация | API keys, JWT, OAuth |
| Трансформация | Преобразование запросов/ответов |
| Кэширование | Кэширование ответов для снижения нагрузки |
| Мониторинг | Логирование, метрики, трейсинг |
AWS API Gateway
AWS предлагает два типа API Gateway:
| Тип | Стоимость | Для CRC |
|---|---|---|
| REST API | $3.50/M запросов | Больше возможностей |
| HTTP API | $1.00/M запросов | Рекомендуется для CRC |
HTTP API дешевле на 70% и достаточен для CRC.
Создание HTTP API
# Создание HTTP API
aws apigatewayv2 create-api \
--name crc-api \
--protocol-type HTTP \
--cors-configuration '{
"AllowOrigins": ["https://resume.ivanpetrov.com"],
"AllowMethods": ["GET", "OPTIONS"],
"AllowHeaders": ["Content-Type"],
"MaxAge": 86400
}'
# Создание интеграции с Lambda
aws apigatewayv2 create-integration \
--api-id API_ID \
--integration-type AWS_PROXY \
--integration-uri arn:aws:lambda:us-east-1:123456789012:function:visitor-counter \
--payload-format-version "2.0"
# Создание маршрута
aws apigatewayv2 create-route \
--api-id API_ID \
--route-key "GET /count" \
--target "integrations/INTEGRATION_ID"
# Создание стадии (auto-deploy)
aws apigatewayv2 create-stage \
--api-id API_ID \
--stage-name prod \
--auto-deploy
Разрешение Lambda Invoke
# Даём API Gateway право вызывать Lambda
aws lambda add-permission \
--function-name visitor-counter \
--statement-id apigateway-invoke \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-east-1:123456789012:API_ID/*/GET/count"
Результат
URL: https://API_ID.execute-api.us-east-1.amazonaws.com/prod/count
Альтернатива: Lambda Function URL
Для простых случаев (как CRC) можно использовать Lambda Function URL вместо API Gateway:
# Создаём Function URL (бесплатно!)
aws lambda create-function-url-config \
--function-name visitor-counter \
--auth-type NONE \
--cors '{
"AllowOrigins": ["https://resume.ivanpetrov.com"],
"AllowMethods": ["GET"],
"AllowHeaders": ["Content-Type"]
}'
Lambda Function URL -- это бесплатно (входит в стоимость Lambda). Для CRC это отличная альтернатива.
Azure API Management
Azure Functions уже имеет HTTP endpoint
В Azure Functions HTTP trigger создаёт endpoint автоматически:
https://crc-visitor-counter.azurewebsites.net/api/count
Для CRC этого достаточно. API Management нужен для более сложных сценариев.
Когда нужен Azure API Management
# Создание API Management (Consumption tier -- serverless)
az apim create \
--name crc-apim \
--resource-group crc-resources \
--publisher-name "CRC" \
--publisher-email "[email protected]" \
--sku-name Consumption
# Импорт Function App как API
az apim api import \
--resource-group crc-resources \
--service-name crc-apim \
--path /api \
--specification-format OpenApi \
--specification-url "https://crc-visitor-counter.azurewebsites.net/api/swagger.json"
CORS в Azure Functions
// host.json
{
"extensions": {
"http": {
"routePrefix": "api"
}
},
"cors": {
"allowedOrigins": [
"https://resume.ivanpetrov.com"
],
"supportCredentials": false
}
}
GCP API Gateway
Cloud Functions уже имеет HTTP endpoint
Как и Azure, GCP Cloud Functions с HTTP trigger создаёт endpoint:
https://us-central1-PROJECT_ID.cloudfunctions.net/visitor-counter
Когда нужен GCP API Gateway
# Создание API config
cat > api-config.yaml << 'EOF'
swagger: '2.0'
info:
title: CRC API
version: '1.0'
host: crc-api-HASH.apigateway.PROJECT_ID.cloud.goog
schemes:
- https
paths:
/count:
get:
operationId: getCount
x-google-backend:
address: https://us-central1-PROJECT_ID.cloudfunctions.net/visitor-counter
responses:
'200':
description: Success
EOF
# Создание API
gcloud api-gateway apis create crc-api
# Создание конфигурации
gcloud api-gateway api-configs create crc-config \
--api=crc-api \
--openapi-spec=api-config.yaml
# Создание gateway
gcloud api-gateway gateways create crc-gateway \
--api=crc-api \
--api-config=crc-config \
--location=us-central1
CORS: Cross-Origin Resource Sharing
Проблема
Ваш фронтенд на resume.ivanpetrov.com делает fetch-запрос к API на api.ivanpetrov.com. Это кросс-доменный запрос, и браузер блокирует его по умолчанию из соображений безопасности.
Решение: CORS-заголовки
Access-Control-Allow-Origin: https://resume.ivanpetrov.com
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
Где настраивать CORS
| Провайдер | Где настраивать |
|---|---|
| AWS HTTP API | В конфигурации API Gateway |
| AWS Lambda URL | В конфигурации Function URL |
| Azure Functions | В host.json или Application Settings |
| GCP Cloud Functions | В коде функции (response headers) |
Частая ошибка: Access-Control-Allow-Origin: *
# ПЛОХО для production (но OK для разработки):
'Access-Control-Allow-Origin': '*'
# ХОРОШО для production:
'Access-Control-Allow-Origin': 'https://resume.ivanpetrov.com'
* разрешает запросы с любого домена. Для CRC это не критично, но для production-систем используйте конкретный домен.
Тестирование API
curl
# Простой GET-запрос
curl https://API_ID.execute-api.us-east-1.amazonaws.com/prod/count
# С заголовками (проверка CORS)
curl -v -H "Origin: https://resume.ivanpetrov.com" \
https://API_ID.execute-api.us-east-1.amazonaws.com/prod/count
# OPTIONS preflight
curl -X OPTIONS \
-H "Origin: https://resume.ivanpetrov.com" \
-H "Access-Control-Request-Method: GET" \
https://API_ID.execute-api.us-east-1.amazonaws.com/prod/count
Ожидаемый ответ
{
"count": 42
}
С заголовками:
HTTP/2 200
content-type: application/json
access-control-allow-origin: https://resume.ivanpetrov.com
access-control-allow-methods: GET, OPTIONS
Сравнение подходов
| Параметр | AWS HTTP API | Azure Functions | GCP Cloud Functions |
|---|---|---|---|
| Отдельный API GW | Да | Нет (встроено) | Нет (встроено) |
| CORS | В API Gateway | В host.json | В коде |
| Custom domain | Через API Gateway | Через Function App | Через API Gateway |
| Rate limiting | Встроено | Через APIM | Через API Gateway |
| Стоимость | $1/M запросов | Бесплатно | Бесплатно |
| Free Tier | 1M запросов/мес | Неограниченно | Неограниченно |