Back to portfolio

Highly Scaleable Image Manipulation API

back-end development | JavaScript | Sharp npm module | Github | AWS Lambda

Link to GitHub repository: imageResizer

Built in Node.js; deployed on AWS Lambda via Amazon API Gateway

Test API here

Overview

While putting together my web development projects I kept running into issues regarding my images. Sometimes an image would be the incorrect dimensions, needs cropping, or could use rotation to fit better on page. This created a need for me to create an image resizer that would load images quickly exactly as I want them to look.

Objectives

As I began the building process, I made this list of objectives to keep me on track:

  • Needs to support image sizes from very large monitors to small mobile devices
  • Performs mirroring for AB testing user conversion rates
  • Since web traffic can spike very quickly, we need scaleable infrastructure to support on demand image processing
  • Need a caching layer for duplicate image requests

Process

Before any actual coding took place, I registered with AWS Lambda here! Once my registration was locked and loaded I created my AWS lambda zip with `sharp` and `request` npm packages. This link will help you in the steps in getting set up!

Writing the code:

  • First stop, I chose an image library that works in with one of lambda's supported languages! I chose Sharp as it was the easiest to navigate and it was widely used and celebrated on GitHub
  • Then, I chose a url downloading library to simplify fetching images. I used Request for the same reason as Sharp-easily to follow, versatile, well-regarded.
  • Then, using Sharp I created an image transformation pipeline that will perform the transformation specified by the url parameters
  • Finally, I returned the base 64 encoded image! Right now, my image resizer only can make .png files by taking in the URL but I'll expand to more formats soon!

Deploying to Lambda gateway:

  • I assigned an AWS IAM role that has cloudwatch enabled. CloudWatch is useful because it can automatically react to changes (so, changes to your image in this case) and monitor your log files.
  • Then, I increased the memory limit to speed up API the response. More memory in this case means faster conversions.

Configuring API gateway

  • I converted the URL parameters to event.query parameters for the Integration Reqeust. I used Kenn Brodhagen's wonderful tutorial here. His step by step process was a life-saver in getting this set up.
  • The response header needs to be set to image/png inside the API Gateway.
  • The transformed images must be encoded in base64 to comply with Lambda's text only resposne.
  • API caching was enabled since all requests to the api should have deterministic responses.

Challenges:

AWS Lambda doesn't have a good way for rapidly testing your code locally. It takes several minutes to rebuild, redeploy, and run tests that could all fail because of syntax error. The simplest way to test your code is by setting up a simple Express server is a quick way to debug logical coding. However, This doesn't emulate many of the API Gateway configurations though which can be quite confusing the first time you use them. There are some frameworks that are attempting to bridge the gap between local development and a full serverless deployment. I will be evaluating them for any furture serverless projects.

Results

Now I have a fast-loading, effective image manipulator that resizes, blurs, rotates, and crops .png files. Try here to have a look yourself!