Мне не удается включить поддержку двоичного кода с помощью шлюза API с Terraform в Localstack.
Пример прост: Lambda генерирует аватары, похожие на аватары Github, и возвращает изображение как PNG.
Lambda (прокси) интегрирована со шлюзом API (идея: GET /avatars/{username}
- ›image / png)
Когда я вызываю опубликованный URL (я делаю это в Localstack), API всегда возвращает изображение в кодировке Base64 без применения CONVERT_TO_BINARY
.
Вот основные шаги ...
- Создайте ReST API:
resource "aws_api_gateway_rest_api" "api" {
name = var.api_name
# enable support for 'image/png'
binary_media_types = [
"image/png",
]
}
- Создайте конечную точку
GET /avatars/{username}
:
# ReST API endpoint 'avatars'
resource "aws_api_gateway_resource" "avatars" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_rest_api.api.root_resource_id
path_part = "avatars"
}
# 'avatars' endpoint resource path parameter.
resource "aws_api_gateway_resource" "resource" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_resource.avatars.id
path_part = "{username}"
}
# Defines the resource HTTP method (verb or action).
resource "aws_api_gateway_method" "get-avatar" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = "GET"
authorization = "NONE"
request_parameters = {
"method.request.path.username" = true
}
}
- Интегрируйте конечную точку
GET /avatars/{username}
в ReST API:
resource "aws_api_gateway_integration" "resource_integration" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.get-avatar.http_method
type = "AWS_PROXY"
integration_http_method = "POST"
uri = aws_lambda_function.lambda.invoke_arn
passthrough_behavior = "WHEN_NO_MATCH"
request_parameters = {
"integration.request.path.id" = "method.request.path.username"
}
}
resource "aws_api_gateway_integration_response" "get-avatar-response" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.get-avatar.http_method
status_code = "200"
content_handling = "CONVERT_TO_BINARY"
}
- Разверните ReST API:
resource "aws_api_gateway_deployment" "deployment" {
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "stage"
depends_on = [aws_api_gateway_method.get-avatar, aws_api_gateway_integration.resource_integration]
}
API Gateway предполагает, что текстовые данные представляют собой строку в кодировке base64, и выводит двоичные данные в виде большого двоичного объекта в кодировке base64.
Вот простой обработчик Lambda (конечно, в классном Go! :-))
func handler(ctx context.Context, evt events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
log.Printf("Processing request data for request %s.\n", evt.RequestContext.RequestID)
username := evt.PathParameters["username"]
if len(username) == 0 {
code := http.StatusBadRequest
msg := http.StatusText(code)
return events.APIGatewayProxyResponse{Body: msg, StatusCode: code}, nil
}
key := []byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
icon := identicon.New7x7(key)
log.Printf("creating identicon for '%s'\n", username)
pngdata := icon.Render([]byte(username))
body := base64.StdEncoding.EncodeToString(pngdata) // <= Base64 Encoded Response
return events.APIGatewayProxyResponse{
Body: body,
Headers: map[string]string{
"Content-Type": "image/png",
},
IsBase64Encoded: true, // <= Is Base64 Encoded? Yes!
StatusCode: 200,
}, nil
}
Вызов конечной точки с помощью curl (например):
curl 'http://localhost:4566/restapis/8nilx7bu49/stage/_user_request_/avatars/type-a-username-here'
... он отвечает изображением в кодировке Base64. Фактически, если я передаю вывод в base64 -d
сохранение содержимого, изображение будет правильным:
curl 'http://localhost:4566/restapis/8nilx7bu49/stage/_user_request_/avatars/type-a-username-here' -s | base64 -d > test.png
Может ли кто-нибудь указать мне, что я упускаю или путаю?
Всего наилучшего, Лука