Serving files using AWS Lamda and API Gateway and Serverless — 2020

Karthik S Kumar
Jul 18 · 3 min read

This example illustrates how we can serve files using AWS Lamda and AWS API Gateway using Serverless. Amazon API Gateway supports serving binary files. We will be writing a Serverless API that serves an image.

Before you start you will need to have

  1. Basic knowledge of Serverless
  2. Node.js and npm installed in your system
  3. Amazon web services (AWS) account

You can refer this blog if you are not familiar with the basics of serverless


Project Setup

We will create a project folder and initialize an npm project. Create a new serverless service in the project folder.

mkdir my-serverless-project
cd my-serverless-project
npm init -y
serverless create --template aws-nodejs

The Serverless framework generates a boilerplate for the application. Out of these, handler.js and serverless.yml are significant.

Now we will install serverless-offline which is a plugin used to run the Serverless framework on the localhost. This will emulate the Lambda and API Gateway on our local machine to speed up your development cycles. Otherwise, we will have to deploy the service to AWS every time to test a change.

npm install -D serverless-offline

Modify the serverless.yml file to include the plugin.

service:
name: serverless
plugins:
- serverless-offline
provider:
name: aws
runtime: nodejs12.x
apiGateway:
minimumCompressionSize: 1024
environment:
AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
functions:
hello:
handler: handler.hello
events:
- http:
method: get
path: /

Now run the following command in your project folder to start the serverless offline server.

serverless offline start

We have made a basic serverless app. Goto http://localhost:3000/dev to view the development server.

Set up binary file serving in API Gateway

We will use a plugin called serverless-apigw-binary to serve files through the API Gateway.

npm install -D serverless-apigw-binary

Add an image file to the project folder. This is for the ease of demonstration. The binary file can be of any type and from different sources. Here we are serving a PNG image. We will need to explicitly add a line in serverless.ymlto include the image file while deploying. By default serverless will ignore all the files that are not referenced in the application. Modify the serverless.yml as follows

service:
name: serverless
include:
- my-image.png
plugins:
- serverless-offline
- serverless-apigw-binary
custom:
apigwBinary:
types:
- '*/*'
provider:
name: aws
runtime: nodejs12.x
apiGateway:
minimumCompressionSize: 1024
environment:
AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
functions:
hello:
handler: handler.hello
events:
- http:
method: get
path: /

We will need to modify the handler.js accordingly. API Gateway does not support sending binary data directly, rather as a string. isBase64Encoded: true will let the API Gateway know that binary data is encoded in base64.

'use strict';const fs = require('fs');
module.exports.hello = async (event) => {
const file = fs.readFileSync('my-image.png');
return {
statusCode: 200,
headers: {
'Content-Type': 'image/png',
},
body: file.toString('base64'),
isBase64Encoded: true,
};
};

Deploy the serverless application using serverless deploy . Voila, we have successfully served binary files through AWS Lambda and API Gateway.


Wrapping up

This article walked you through the process of creating a Serverless app that serves binary files. This will be helpful when we are creating an application that involves serving binary files such as a screenshot app that takes screenshots of images. You can see the whole code here

JavaScript In Plain English

New articles every day.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store