從 API Gateway 到 Lambda 的二進制正文傳遞
我想我已經密切關注我到目前為止找到的文件和教程,但我仍然可以使用它。我只是無法說服 AWS 不要觸摸我在正文中發布的二進制數據。
在我的應用程序中,我將原始 API 請求的 Content-Type 和 Accept 標頭都設置為 application/x-msgpack,我已將其定義為二進制支持下的二進制媒體類型:
我沒有在方法請求中設置任何內容:
在集成請求中,我沒有啟用代理並且我啟用了請求正文直通:
我為 API Gateway 執行啟用了 CloudWatch 日誌,我可以看到 AWS 仍在對我的二進制數據進行 base-64 編碼:
17:30:29 開始執行請求:... 17:30:29 HTTP 方法:POST,資源路徑:/... 17:30:29 方法請求路徑:{} 17:30:29 方法請求查詢字元串:{} 17:30:29 方法請求頭:{ 接受=應用程序/x-msgpack, 內容類型=應用程序/x-msgpack, ... } 17:30:29 轉換前的方法請求正文:[二進制數據] 17:30:29 端點請求 URI:https://... 17:30:29 端點請求標頭:{ 接受=應用程序/x-msgpack, ... [截斷 - 我沒有看到其餘的標題] } 17:30:29 轉換後的端點請求正文:[Base-64 編碼的二進制數據] 17:30:29 發送請求到 https://...
請注意,端點請求標頭已在 CloudWatch 日誌中被截斷(我自己沒有為這個問題截斷它們)。因此,我看不到 Content-Type 標頭是什麼。
請注意帶有“轉換前的方法請求正文”和“轉換後的端點請求正文”的行。為什麼還要將二進制數據轉換為 base-64?
到目前為止我使用的來源是:
- http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html
- https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/
- http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-workflow.html
- http://docs.aws.amazon.com/apigateway/api-reference/resource/integration/#contentHandling
更新
我通過 AWS CLI 檢查了集成設置並得到了這個:
> aws apigateway 獲取集成 \ --rest-api-id ... \ --資源ID ... \ --http 方法 POST { “整合響應”:{ “200”:{ “選擇模式”:“”, “狀態程式碼”:“200” } }, "contentHandling": "CONVERT_TO_TEXT", "cacheKeyParameters": [], “uri”:“……”, "httpMethod": "POST", "passthroughBehavior": "WHEN_NO_TEMPLATES", "記憶體命名空間": "...", “類型”:“AWS” }
我注意到了這
"contentHandling": "CONVERT_TO_TEXT"
一點,並嘗試將其覆蓋為""
(空值,這反過來完全刪除了該屬性)並"CONVERT_TO_BINARY"
通過執行以下操作:> aws apigateway 更新集成 \ --rest-api-id ... \ --資源ID ... \ --http 方法 POST \ --patch-operations '[{"op":"replace","path":"/contentHandling","value":""}]'
我現在看到端點請求被保存為二進制:
10:32:21 轉換後的端點請求正文:[二進制數據]
但是,我收到此錯誤:
10:32:21 轉換前的端點響應正文:{"Type":"User","message":"Could not parse request body into json: Unexpected character ((CTRL-CHAR, code 129))...
而且我的 Lambda 函式的 CloudWatch 日誌中沒有任何活動。而且我的 Lambda 函式不是試圖將傳入數據解析為 JSON 的函式。因此,仍然在 API-Lambda 集成路徑的某個地方,數據被解析為 JSON,而不是單獨作為二進製文件。
我一直在嘗試將二進制數據從 APIG 發送到 Lambda。我嘗試的所有 APIG 選項都轉換為 Base64。我現在認為這是由於 Lambda 攝取了 JSON 事件數據。
在 python 中工作時,我無法使用 @AtesGoral npmjs 壓縮,因此最終使用了 APIG 到 S3 的解決方案(<10MB 二進制工作)並通過 S3 事件觸發器觸發 Lambda 函式。FWIW:Lambda 6MB 限制和 Base64 編碼(最大 4.4MB 二進制輸入)使得在不先寫入 S3 的情況下使用 APIG -> Lambda 實現 S3 分段上傳是不可能的。