20

We have developed an application that offers serveral rest services and supports Accept-Encoding header to return compressed content through Content-Encoding:gzip header value.

This application is deployed on ec2 instances on aws and when we send a request with Accept-Encoding value set the response is correctly built.

We want to expose this api by using api gateway but it is just working for not compressing requests. When we send a request asking for gzipped content the Content-Encoding header is set correctly but the response content is corrupt.

Do we have to set some special parameter or configuration in integration response or method response steps?

Regards.

althor
  • 739
  • 2
  • 9
  • 21

6 Answers6

17

Since Dec 19, 2017. AWS API Gateway has encoding support.

After the API is created, just go to Settings and select Content Encoding Enable.

See example

Also here is the AWS official release post.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Pablo Arias Mora
  • 389
  • 4
  • 11
  • 11
    If you manage CORS headers in your app, don't forget to allow any necessary response headers in your pre-flight response. I was missing `Content-Encoding` and despite having this API option enabled, API Gateway was not compressing my responses. The header `Access-Control-Allow-Headers: Content-Type,Content-Encoding` in my response to the CORS OPTION pre-flight seems to have fixed it. – Carl G Mar 16 '18 at 21:05
  • 2
    Also I think I had to deploy the API to the stage after enabling this setting. Even though nothing else changed in my API, and the setting appears to be set at a 'api' level as opposed to an 'individual stage' level, I didn't see the compression in my prod stage until I re-deployed the API to that stage. – Carl G Mar 24 '18 at 11:13
  • @CarlG What do you mean you had to deploy to Stage? What if I was working on stage already and modified the settings to enable compression? – elena Feb 06 '19 at 17:25
9

Unfortunately, API Gateway does not currently support HTTP compression. However, it is in consideration for future development.

For now, you will need to return uncompressed content from your endpoint (i.e. omit Accept-Encoding header) in order to proxy it through API Gateway.

If it works for your use case you could alternatively base64 encode the compressed content, proxy it through API Gateway, and decode it on the client.

Thanks, Ryan

RyanG
  • 3,973
  • 25
  • 19
  • It does support it now, since 2018 https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-receive-response-with-compressed-payload.html – Sigex Apr 22 '21 at 10:38
  • 1
    @Sigex yes but only for REST APIs. Http apis dont support compression yet. – Wrathful Dudu Aug 12 '22 at 01:06
7

Only a workaround, but if you set Accept-Encoding: identity you should receive the result correctly (contrary to the linked discussion I have found it works for POST and GET).

Dan Gravell
  • 7,855
  • 7
  • 41
  • 64
  • 3
    After pulling my hair out for hours and hours, I can confirm this obscure piece of info works. With this issue with GZipping and mucking around with getting CORS to work, it has been a nightmare getting set up. I am sure thousands have not had my perseverance and just given up. Get your act together Amazon. – Lobos Jul 25 '17 at 02:18
  • @Lobos Same here, I've been struggling with the setup for 2 days now. It's been a nightmare. – The Onin Sep 07 '17 at 21:07
  • Update: I've given up. – The Onin Sep 07 '17 at 21:33
  • So have I; installed Kong instead! API gateway is pretty expensive anyway. – Dan Gravell Sep 08 '17 at 07:49
3

Although this question is a bit old, I'd like to add an answer since this question is top-most viewed one. In fact, there are 2 scenarios related to returning the compressed content.

The first scenario is when you want API Gateway to compress the content. As the accepted answer suggests, you can enable the content encoding on your API then deploy it.

The second scenario is your integration endpoint already compressed the result and you just want to bypass it via API Gateway. The traditional workaround was configuring it as a binary media type. However, this might be problematic since it will begin to treat all response with the media type as a binary. Additionally, if you need to deal with multiple media types, your only choice would be setting it as '*'. If you're using non-proxy integration, you will lose a chance to transform the result.

To address the second issue, now API Gateway implicitly assumes a response result as binary when a proxy integration is used AND the content is encoded (the response has Content-Encoding with the value other than 'identity'). You don't need to configure binary media types any more when these conditions are met. However, if you're returning the actual binary media (e.g. image, video), you still need to configure them as binary media type(s).

You might wonder what happens when you have both scenarios. The short answer is that API Gateway will not compress again when the response already has Content-Encoding header.

Hopefully this helps.

Jaewoo Ahn
  • 59
  • 1
  • 1
    I'm dealing with the second scenario (my integration Lambda returns gzipped content, which I tested stand-alone) but the API gateway is messing up the response. My Lambda returns the header "Content-Encoding":"gzip" which I tested in the API Gateway web console. Any ideas how to get API gateway to treat the response as binary? – Jacob Mouka Nov 23 '19 at 18:16
  • @JacobMouka and everyone else who finds my comment: I encoded the response body in base64 and in the lambda return object there's a flag "isBase64Encoded" in HTTP API. – marcellsimon Apr 04 '22 at 21:42
2

I made it work by adding Accept-Encoding to AWS API Gateway Integration Request

Step 1: Go to AWS API Gateway console, click on Integration Request enter image description here

Step 2: Add Accept-Encoding to HTTP Headers section, value 'identity' (need single quotes) enter image description here

Step 3: Click Actions -> Deploy API

If you're using AWS CloudFormation, you can add yaml Integration: RequestParameters: integration.request.header.Accept-Encoding: "'identity'

ittus
  • 21,730
  • 5
  • 57
  • 57
0

To allow GZipped content from HTTP proxy endpoint you can add */* in "Binary media types" found at "Binary Support" section of your API.

Josh E
  • 7,390
  • 2
  • 32
  • 44