1

I am trying to enable gzip compression on my service endpoints. My original rest service is a spring boot web application. Which I easily enabled the gzip thanks to this answer.

The problems starts when I try to integrate it with AWS public api. I'm using swagger integration.

If I don't do anything on public api, requests through postman or curl to public api never returns encoded response or headers related to encoding.

So I have tried passing the Accept-Encoding header of request trough the public api to my original rest service by applying the specific example mappings as shown below:

{
    "/brand/list": {
        "get": {
            "summary": "Get a list of brands",
            "description": "List",
            "operationId": "List",
            "produces": [
                "application/json",
                "application/x-www-form-urlencoded",
                "text/plain"
            ],
            "parameters": [
                {
                    "name": "Accept-Encoding",
                    "in": "header",
                    "required": false,
                    "type": "string"
                }
            ],
            "responses": {
                "200": {
                    "description": "OK",
                    "schema": {
                        "$ref": "#/definitions/DataModelOfBrandCatalogue"
                    },
                    "headers": {
                        "Content-Encoding": {
                            "type": "string"
                        }
                    }
                },
                "400": ..., ...., "500"
            },
            "x-amazon-apigateway-integration": {
                "uri": "http://original.service.com/brand/list",
                "responses": {
                    "200": {
                        "statusCode": "200",
                        "responseParameters": {
                            "method.response.header.Content-Encoding": "integration.response.header.Content-Encoding"
                        }
                    },
                    "400": ..., ...., "500"
                },
                "requestParameters": {
                    "integration.request.header.Accept-Encoding": "method.request.header.Accept-Encoding",
                    "integration.request.header.Content-Type": "'application/json'"
                },
                "passthroughBehavior": "when_no_match",
                "httpMethod": "GET",
                "type": "http"
            },
            "tags": []
        }
    }
}

Though when I deploy this description, something interesting happens. When I do a curl request like below, the response is encoded indeed. If I remove Accept-Encoding parameter from curl, the response is not encoded as expected. Everything's okay till here.

curl -X GET   https://api.service.com/brand/list   -H 'Cache-Control: no-cache'   -H 'Accept-Encoding: gzip'

But when I go to postman, and make the same query (I'm sure they are same, as I have generated the curl command through POSTMAN's own tool - code button) it's not getting any response back. Postman Console shows Error: incorrect header check.

What am I missing? Is my strategy wrong? Or do I miss some details?

Edit: I thought the encoded response was correct, but when I add --compressed to my curl request, I noticed it's giving error below, so the encoding is not correct either.

curl: (61) Error while processing content unencoding: invalid block type

Tolga Evcimen
  • 7,112
  • 11
  • 58
  • 91

1 Answers1

1

As the integration response payload(from your service endpoint) is already compressed, you should let API Gateway know that it is binary.

Previously, you can do it only by explicitly setting binary media types in your API settings. You can use a specific media type such as 'application/json' or '/' for all media types. As you expected, there is a downside. Now it will treat the content as binary always whether it is compressed or not.

Recently there was an update rolled out to handle the integration response as binary IMPLICITLY when the response has 'Content-Encoding' header with the value other than 'identity'. For example, if your response has 'Content-Encoding: gzip', then API Gateway will handle it as binary without any explicit binary media type setting.

However, this behavior is only available for Lambda/HTTP proxy integrations while you're using HTTP integration. You can set binary media types on it or switch to the HTTP proxy integration to get a benefit of implicit binary support. If you don't use a feature like a response body template, I recommend the latter.

Jaewoo Ahn
  • 59
  • 1