Назад | Перейти на главную страницу

Передача двоичного тела из шлюза API в Lambda

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

В своем приложении я устанавливаю заголовки Content-Type и Accept исходного запроса API на application / x-msgpack, который я определил как двоичный тип мультимедиа в разделе Binary Support:

Я ничего не установил в запросе метода:

В запросе интеграции я не включил прокси и включил сквозную передачу тела запроса:

Я включил журналы CloudWatch для выполнения шлюза API и вижу, что AWS по-прежнему кодирует мои двоичные данные в формате base-64:

17:30:29 Starting execution for request: ...
17:30:29 HTTP Method: POST, Resource Path: /...
17:30:29 Method request path: {}
17:30:29 Method request query string: {}
17:30:29 Method request headers: {
    Accept=application/x-msgpack,
    Content-Type=application/x-msgpack,
    ...
}
17:30:29 Method request body before transformations: [Binary Data]
17:30:29 Endpoint request URI: https://...
17:30:29 Endpoint request headers: {
    Accept=application/x-msgpack,
    ...
    [TRUNCATED - I don't see the rest of the headers]
}
17:30:29 Endpoint request body after transformations: [Base-64 encoded binary data]
17:30:29 Sending request to https://...

Обратите внимание, что заголовки запросов конечной точки были усечены в журналах CloudWatch (я сам не усекал их для этого вопроса). Поэтому я не вижу, что такое заголовок Content-Type.

Обратите внимание на строки с «Тело запроса метода до преобразований» и «Тело запроса конечной точки после преобразований». Почему он все еще преобразует двоичные данные в base-64?

Источники, которые я использовал до сих пор:

Обновить

Я проверил настройку интеграции через AWS CLI и получил следующее:

> aws apigateway get-integration \
  --rest-api-id ... \
  --resource-id ... \
  --http-method POST
{
    "integrationResponses": {
        "200": {
            "selectionPattern": "", 
            "statusCode": "200"
        }
    }, 
    "contentHandling": "CONVERT_TO_TEXT", 
    "cacheKeyParameters": [], 
    "uri": "...", 
    "httpMethod": "POST", 
    "passthroughBehavior": "WHEN_NO_TEMPLATES", 
    "cacheNamespace": "...", 
    "type": "AWS"
}

Я заметил "contentHandling": "CONVERT_TO_TEXT" бит, и я попытался переопределить его на обоих "" (пустое значение, которое, в свою очередь, полностью удалило свойство) и "CONVERT_TO_BINARY" при выполнении:

> aws apigateway update-integration \
  --rest-api-id ... \
  --resource-id ... \
  --http-method POST \
  --patch-operations '[{"op":"replace","path":"/contentHandling","value":""}]'

Теперь я вижу, что запрос конечной точки сохраняется как двоичный:

10:32:21 Endpoint request body after transformations: [Binary Data]

Однако я получаю эту ошибку:

10:32:21 Endpoint response body before transformations: {"Type":"User","message":"Could not parse request body into json: Unexpected character ((CTRL-CHAR, code 129))...

И у меня нет активности в журналах CloudWatch для моей функции Lambda. И моя функция Lambda - это не та, которая пытается анализировать входящие данные как JSON. Таким образом, где-то на пути интеграции API-Lambda данные анализируются как JSON, а не как двоичные.

Я прошел через это же упражнение, пытаясь отправить двоичные данные из APIG в Lambda. Все варианты APIG, которые я пробовал, были преобразованы в Base64. Теперь я считаю, что это происходит из-за того, что Lambda принимает данные о событиях JSON.

Работая в python, я не мог использовать сжатие @AtesGoral npmjs, поэтому в итоге я получил решение APIG для S3 (бинарные работы <10 МБ) и запуск функции Lambda через триггер события S3. FWIW: ограничение Lambda 6 МБ и кодировка Base64 (максимальный двоичный ввод 4,4 МБ) делают невозможным реализацию многостраничной загрузки S3 с использованием APIG -> Lambda без предварительной записи в S3.