Building your First Serverless App in Node.js with AWS Lambda + S3 + API Gateway
In this article, we are going to build a simple Serverless application using AWS Lambda with S3 and API Gateway. We’ll use Node.js 8.10.0 which was added to AWS Lambda a few weeks ago.
AWS Lambda provides support for inline code edit, so we don’t need any special tool for that. At the end of this tutorial,, our application will be able to perform ImageMagick operation on AWS Lambda.
A Few Words about Serverless:
Steve Faulkner Software Engineer at LinkedIn, defines Serverless as:
The way I describe it is: functions as a service are cloud glue. So if I’m building a model airplane, well, the glue is a necessary part of that process, but it’s not the important part. Nobody looks at your model airplane and says: “Wow, that’s amazing glue you have there.” It’s all about how you craft something that works with all these parts together, and FaaS enables that.
If you want to read more about Serverless, I suggest reading: Serverless is Eating the Stack and People are Freaking out — As They Should Be by Forrest Brazeal and Serverless Architectures by Martin Fowler.
The source code is available on github.com/WaleedAshraf/serverless-app
We will follow these steps,
1: Setup a new function on AWS Lambda
2: Create new API Gateway
3: Test API Gateway
4: Add ImageMagick to Lambda Function
5: Setup S3 Bucket
6: Add S3 support in Lambda Function
1: Setup a new function on AWS Lambda:
Important: You must keep AWS Region set to US East (N. Virginia) from the top right corner of your AWS account.
Go to the AWS Lambda Homepage and create a New Function from the top right corner.
You can name your function whatever you like, and set the runtime to Node.js 8.10.
Create a new role from templates, name it whatever you like and then select “Basic Edge Lambda Permissions” from policy templates.
After creating the function, replace the code with this and click save.
sendRes function is returning
HTML response to the caller (API Gateway).
2: Create new API Gateway:
Now we need to create a new API Gateway, which will trigger our Lambda function. First, add API Gateway from Triggers area on the left side.
After adding it here, click save from the top right corner. We have added the trigger. Now we need to create a new API Gateway and link it with our function. To do this, go to API Gateway Homepage and create a new API.
- You can name it whatever you like and keep the endpoint regional.
- After that, click on the Create Method to add a new route to API.
- Select Integration type as Lambda function.
- Check Lambda Proxy Int.
- Region is use-east-1
- Lambda function is fooImage.
That’s it. Save the API with these settings. Remember that after you make any change in the API, don’t forget to deploy it. Click on Deploy API from actions tab.
- Select “New Stage”
- Name it whatever you like.
- Click “Deploy”
Few things to know before we start testing our Lambda function.
- On Lambda function page, go to monitoring tab and click Jump to Logs to see logs output in AWS CloudWatch service.
- On Lambda Function page, scroll down to Basic Settings window and increase the timeout to 2 min+. This is to let
request/responsecomplete before Lambda terminates function execution.
- To send the request to the Lambda function, we will need it’s URL. You can get it by clicking on API Gateway, at the bottom you will see Invoke URL.
3: Test API Gateway:
For testing, we are going to use Postman. We will send a simple GET request to our Invoke URL. According to our current Lambda function, it should respond with “Hello”
🙌 It’s working as expected. 🎉
4: Add ImageMagick to Lambda Function:
Time to write some code.
ImageMagick library is already available on all Lambda instances. So we just need to require it and use it. We’ll use a generic function
convert which can perform multiple operations like rotate, flip, change colours etc.
We will also use
fs module from Node.js library to deal with files.
Here, I’m taking
operation from query-string parameters of the request. If it is
“convert”, then we will call our
operate function. operate function is expecting two params in the body, one is
base64 Image as string and second is
customArgs a comma separated string which would tell us what operation to perform on the image. i.e
im.convert function takes an array of three arguments as input.
[‘inputFilePath’,’operation to perform’,‘outputFilePath’] .
im.convert function, I have written a wrapper around it
performConvert which takes params as input and return promise.
performConvert, I’m reading the output file into Buffer and calling
fs.unlinkSync to delete the file. After that, I’m sending
HTML as response which includes
Let’s test it. We need to convert the image into base64 string. You can easily do it online. I used this site.
As you see above, I have set
operation=convert in query param. Sending POST request with the raw body. Don’t forget to set format type to JSON.
“-flip” to flip image upside-down.
Now we just need to setup S3 bucket to save output images.
5: Setup S3 Bucket:
Go to the S3 Homepage and create a new bucket.
- Name it whatever you like.
- Set Region to US East(N. Virginia)
- Go to Next step.
- We’ll keep this bucket public. (Don’t want to get into permissions details.)
- Select Grant public read access to this bucket.
- Click Next and you are done.
After you create the bucket. Go to the Permissions tab, click Everyone on the left side, and check List Objects, and Write Objects from the right side. Click Save.
- We also need to update the Bucket Policy as shown. You may copy it from here.
- Just remember to use your bucket name at line 10.
- Update the CORS Configuration as shown. You may copy it from here.
The last thing is to create a folder in bucket named images.
Now, we are done with S3 setup. Save everything and go back to Lambda function.
6: Add S3 support in Lambda Function:
We’ll require S3 from AWS library, which is also available on Lambda by default.
I have created a function
putfile which is using
s3.putObject function to upload the image to S3. It needs Bucket name, Key
(foldername/filename), and data in Body.
Before sending the response, I’m calling this function at line 50 to upload the image to S3. After a test, you should be able to see uploaded image in the S3 folder.
We are done. 🎉 👐
The source code is available on github.com/WaleedAshraf/serverless-app where I have also created a HTML page to submit image through a form.
If you are developing in Node.js, must check my previous articles in Node.js Collection.