Serverless-express: why return base64 encoded?

Created on 26 Sep 2017  Â·  9Comments  Â·  Source: vendia/serverless-express

Hi,

If I understand correctly from #64 and #66 that listing 'application/json' in the binaryMimeTypes is for gzip support.

I tried to mimic the example with a simpler version. However I got the base64 encoded return.
Below is the setting for lambda.js and app.js

````javascript
// lambda.js
'use strict'
const awsServerlessExpress = require('aws-serverless-express')
const app = require('./app')

// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely
// due to a compressed response (e.g. gzip) which has not been handled correctly
// by aws-serverless-express and/or API Gateway. Add the necessary MIME types to
// binaryMimeTypes below, then redeploy (npm run package-deploy)
const binaryMimeTypes = [
'application/javascript',
'application/json',
'application/octet-stream',
'application/xml',
'font/eot',
'font/opentype',
'font/otf',
'image/jpeg',
'image/png',
'image/svg+xml',
'text/comma-separated-values',
'text/css',
'text/html',
'text/javascript',
'text/plain',
'text/text',
'text/xml'
]
const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes)

exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context)
javascript
// app.js
'use strict'
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const compression = require('compression')
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')
const app = express()

app.use(compression())
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(awsServerlessExpressMiddleware.eventContext())

app.get('/testing', function (req, res) {
res.json({testing: 'testing'})
})

module.exports = app
````

I got return value of
eyJ0ZXN0aW5nIjoidGVzdGluZyJ9
instead of
{testing: 'testing'}

Most helpful comment

For those who's struggling the useage of binaryMimeTypes, here is my sharing. Please correct me if anything wrong.

The whole thing of adding MIME types to binaryMimeTypes is for compression. e.g. you want to gzip the application/json payload. let's first quote from @brettstack :

"Express response -> compression/gzip middleware (if you use it) -> aws-serverless-express (encodes to base64 if content-type is specified in binaryMimeTypes in Lambda handler) -> API Gateway (decodes base64 if content-type matches a binary mime type specified on API) -> Client"

here is my little supplement for his quote.
1) Lambda doesn't support binary type, so aws-serverlesss-express needs to encode the compression to base64
2) API gateway doesn't support gzip, but support binary type, so what it does is to let the express middleware do the compression, and decodes the base64 encoded payload received from lambda and finally pass to client.

All 9 comments

For those who's struggling the useage of binaryMimeTypes, here is my sharing. Please correct me if anything wrong.

The whole thing of adding MIME types to binaryMimeTypes is for compression. e.g. you want to gzip the application/json payload. let's first quote from @brettstack :

"Express response -> compression/gzip middleware (if you use it) -> aws-serverless-express (encodes to base64 if content-type is specified in binaryMimeTypes in Lambda handler) -> API Gateway (decodes base64 if content-type matches a binary mime type specified on API) -> Client"

here is my little supplement for his quote.
1) Lambda doesn't support binary type, so aws-serverlesss-express needs to encode the compression to base64
2) API gateway doesn't support gzip, but support binary type, so what it does is to let the express middleware do the compression, and decodes the base64 encoded payload received from lambda and finally pass to client.

Thanks. Glad you figured it out.

On Tue, Sep 26, 2017, 4:30 AM goldenbearkin notifications@github.com
wrote:

Closed #99 https://github.com/awslabs/aws-serverless-express/issues/99.

—
You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/awslabs/aws-serverless-express/issues/99#event-1265525531,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABy6l7Shg71jP0mj889sBaP6_vSVgxs7ks5smOBQgaJpZM4Pj3I0
.

@goldenbearkin I'm having what seem to be encoding problems service PNG image files and thought this might be related. Did you run into this -- and if so, how did you solve it? Thanks.

Just ran into this too. I noticed that API Gateway now supports compressing response bodies which means I think you can drop this workaround.

I am working behind some gateway that is external to aws. Is there a way to turn of the base64 encoding?

@brettstack would be awesome if we can disable the base64 encoding and return just a json.
Is there a way to do that?

@goldenbearkin as you mentioned in API Gateway (decodes base64 if content-type matches a binary mime type specified on API) -> Client

I am assuming if we set binary mime types correctly in API gateway, the matching types of response will be decoded from base64 to its origianl format, while I tried to set */* and it's not working. I still get base64 format for even html file.

Any thoughts?

What's the best practice so far ? I just created a new serverless express lambda, and all I get from the API is an base64 encoded string.

Shouldn't Amplify API automatically handle this ?

I ran into this problem and realized that res.render() calls would render fine in the browser, but anything with express.static() would show up base64'd. I simply had to add the same binary types from lambda.js into my SAM template, somewhat like this:

Resources:
  ExpressServer:
    Type: AWS::Serverless::Api
    Properties:
      ...
      BinaryMediaTypes:
        - application~1javascript
        - application~1json
        ...
        - text~1xml

and Bob is now my uncle.

Was this page helpful?
0 / 5 - 0 ratings