Я думаю, что внимательно следил за документацией и руководствами, которые нашел до сих пор, но я все еще заставляю это работать. Я просто не могу убедить 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.