This is a translated and updated version of the article published a few years ago, if you prefer you can read the outdated version in Portuguese đ§đ· here.
The term Serverless became quite known in the past few years thanks to the popularisation of the use of AWS Lambda, Google Cloud Functions, Azure Cloud Functions and others. The idea behind Serverless computing is the consolidation of the term FaaS (Function as a Service), that exists since 2014 so that developers can create any kind of application without the need to configure, maintain and escalate servers.
The most popular tool to work with Serverless using Node.js is Serverless Framework, because of the long list of providers (AWS, Azure, Tencent, Google, Cloudflare and others) and the huge documentation. This is the tool weâll use in this article.
Thereâs some important things to keep in mind before we start:
- Although the term is âServerlessâ, it doesnât mean that there are no servers behind it, it means that us as developers wonât have to worry about server management, scaling options, optimise availability and more. For example, new instances spin up automatically if you need, without the need to manually provision them.
- Serverless functions are stateless, which means that each request is independent, it doesnât have any relation with previous or future requests.
- The server gets warmed up by a request called cold start and it'll stay alive awaiting another request. If another request is not received in the specified time, the server shuts down. But the cool thing is that, since the server is already warmed up, when another request arrives it can run instantly.
Letâs get our hands dirty then. Iâll show you the very first steps for creating a Serverless function for a prize draw.
Some people are participating in a prize draw to win a trip to the Maldivas and we need to make a service that will receive the list of people participating and randomly choose a winner.
If we were writing this function without using Serverless Framework, this is how weâd do it:
When we are dealing with Serverless Framework we have to be aware of some things first:
The function, when called, receives three parameters: Event, Context and Callback.
Event (Object)
When we do a HTTP request using Node we get the Request object containing a lot of request information, such as headers and body, but when it comes to the Event object the logic is the same, we receive all the request information through it.
Context (Object)
The Context object contains the metadata of the function call. In our case, using AWS Lambda, our context must contain an AWS Request Id, the name of the function, the name of the group log, memory limit, remaining time until the end of the execution and more.
Weâll talk about the Callback parameter later.
So, our function now should look like this:
To get the users array we only need to access it through event.body.users. Now you probably have some questions: âbut where is this array coming from? How do I pass it to the function? How do I even test it?â
Well, calm down, itâs pretty simple đ
Testing a Serverless function
First of all, to make our lives easy letâs create a file called sample-event.js containing an array of all the users participating in the prize draw. Then create a folder called functions and a file called getRandomUser.js inside it, then paste our function's code in it.
Installing and configuring Serverless Framework
Now weâre going to install the Serverless Framework using the command npm i -g serverless
Usually youâll need to install it locally on your project to be able to deploy your functions through a CI, but in our case weâll only need to use the CLI commands, thatâs why weâre installing it globally.
If everything goes well you should get the list of all the available commands by running serverlessâââhelp.
Now letâs configure our Serverless application. Create a serverless.yml file and we'll give our application and function a name:
Here's what is happening:
- service: The name of the service.
- provider: Information about the provider you choose (here we are using AWS but remember that they offer some other options if you prefer).
- runtime: Node version (nodejs10.x, nodejs12.x, nodejs14.x).
- functions: All the functions set up.
- getRandomUser: Our functionâs name. It can be literally anything you want.
- handler: The path to our function. This might be confusing at first, but hereâs some more examples to make it clearer.
If our file was calledapp.js
and our function was exported likemodule.exports.getRandomUser = getRandomUser
, our handler would look likefunctions/app.getRandomUser
.
If our file was calleddrawService.js
and our function was exported likemodule.exports.getDrawWinner = getRandomUser
, our handler would look likefunctions/app.getDrawWinner
.
Now we can test our function locally, and to do this we run serverless invoke local --function getRandomUser --path sample-event.js, the function flag receives the name of the function and the path flag receives the path to our sample array that will be passed to the function within the event parameter.
After running you should have the first winner of our prize draw.
Now letâs make things more interesting, shall we?
Our function as it is can only be invoked manually and thatâs not useful at all, right? One of the many advantages of using Serverless Framework is that we can trigger our function from a HTTP call, or maybe a cron job, or even Alexa. Amazing, right?
What about turning the function into an endpoint that we can call every time we have a new prize draw?
Turn the sample-event.js file into a json file
Weâll modify our configuration a little.
- events: Indicates that weâre gonna use some kind of event to trigger the function. This starts the events configuration.
- http: Here weâre specifying that the event weâre using to trigger the function is a HTTP request.
- path: the path we want to use in our endpoint.
- method: The HTTP method.
- plugins: The list of plugins youâre using. You can find the list of available plugins here.
Now we need to make some changes in our code as well.
Remember the third parameter? We need it now. The Callback parameter, as the name says, is a callback function that youâll call when you want the execution to finish and return something to the client.
The first parameter this function receives is an Error object, which in our case is null. The second parameter is the response, it must contain the status code, but the body can be empty.
Since the function is not deployed yet, weâll need a plugin called serverless-offline
to be able to call it locally. It can be installed by running yarn add -D serverless-offline
.
Run serverless offline , wait for the output and you should see this:
Server ready: http://localhost:3000 đ
Open Postman or any other API Client of your preference and do a POST request passing the content of the sample as the body.
The result of this request should be an object with one of our users, for example:
Nice, right? Now to the last part of this tutorial: deploying our function. If you havenât set your AWS credentials in your .bashrc
or .zshrc
, now it's time to do so. After declaring your credentials, simply run serverless deploy --stage production
, wait for the build/deploy to finish and you have a fully deployed function. At the end of the building the framework gives you an API Gateway url that you can use to make a request to the endpoint we created.
Just for comparison, if we were doing this same API without using Serverless Framework, we would have to create an EC2 instance manually and worry about keeping the server up and monitoring it to make sure it's up 24/7.
Now I recommend you to start exploring Serverless possibilities â as I said before, it can be triggered by a lot of different events which makes it an incredibly powerful tool. Hereâs the Serverless Framework and AWS Lambda documentation to help you through your exploration. Have fun!