Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serverless API gateway transforming request into base64

I have a serverless app which uploads files to s3 (via POST request) and serves them (via GET request)

I am using serverless-apigw-binary and serverless-apigwy-binary plugins to allow me to return binary data in the form of an image. In order to allow the URL to work with browsers, I have to set the binary types to */*.

In order to upload an image the POST endpoint takes a body like { "base64": "..." }. However with this configuration the entire body is coming through as a base64 encoded string. How can I prevent the request body with application/json being transformed?

See serverless.yml below:

service: image-service

custom:
  envName: ${opt:stage, self:provider.stage}
  domains:
    prod: api.<mydomain>
    dev: dev-api.<mydomain>
  customDomain:
    basePath: images
    domainName: ${self:custom.domains.${self:custom.envName}}
    certificateName: "*.<mydomain>"
  apigwBinary:
    types:
      - '*/*'

provider:
  name: aws
  runtime: nodejs8.10
  region: eu-west-1
  memorySize: 1536

  role: ImageRenderingRole

  environment:
    ENV_NAME: ${self:custom.envName}
    APP_NAME: image-service
    BUCKET: <mybucket>

plugins:
  - serverless-offline
  - serverless-domain-manager
  - serverless-apigw-binary
  - serverless-apigwy-binary

functions:
 uploadImage:
   handler: handler.uploadImage
   events:
     - http:
      path: /
      method: POST

  getImage:
    handler: handler.getImage
    events:
      - http:
          path: 'images/{idAndFormat}'
          method: get
          contentHandling: CONVERT_TO_BINARY
          parameters:
              paths:
                idAndFormat: true
like image 978
Ben Flowers Avatar asked Sep 24 '18 12:09

Ben Flowers


1 Answers

You have two options:

  1. Stop using */* as the type selector. This is treating everything as binary, and therefore base64 encoding everything. Unfortunately, you can't express an exception to the rule, only things that follow the rule. You could add a comprehensive list of the types that must be treated as binary, but that sounds fragile to me.

  2. Just accept the base64 JSON and de-base64 it on the other side. This seems easiest. You're using node, it looks like, and there are ample tutorials about this. Sure, it adds some steps and a bit of bloat, but let's be honest, you're using API Gateway and Lambda (which are nice tools, but...) so clearly performance doesn't have to be tuned to the millisecond here.

like image 120
mattbornski Avatar answered Nov 09 '22 03:11

mattbornski