7 February, 2020
Serverless is one of those trends that excite both developers and business people, due to all the potential benefits it can provide. Want to quickly get up to speed with it? Let’s create a serverless application in a couple minutes with Node.js! It’s a great opportunity to find out more about the strengths and weaknesses of serverless application development.
What if I told you that you can create your REST API, deploy it on a server and connect it to the database in just 5 minutes? What’s more, it won’t drain your wallet. Sounds good? Let’s talk today about serverless.
Let’s establish an important fact. Unfortunately, serverless doesn’t mean that our code will magically run without a server 😢. What we get is a solution which allows us to deploy the code without having to manage the whole server infrastructure. Everything runs automatically. All we have to do is bring our code to one of the popular platforms and all of our worries about buying servers, monitoring or scaling can be forgotten.
But it’s not all roses. An important aspect to consider is vendor lock-in. When our configuration is big, it can be hard to migrate from one vendor to another. Each one of them has specific services and different ways to configure them. Once we decide on one of them, it can be very difficult to change it.
With that said, let’s take a closer look on the bright side of serverless 😉
Benefits of serverless app development
I noticed that most developers don’t find it very hard to create custom software or design its architecture. This is our daily bread and we feel comfortable about it. The problem occurs when we need to deploy our application somewhere. I think that people are a little bit afraid of the server layer. Managing and deploying applications correctly might give you a headache.
What if we didn’t have to do it? That is one of the reasons why we should try this new fancy solution called serverless. It allows us to focus solely on writing an app, without having to care about infrastructure.
But what about the cost? Unlike with traditional servers, we only pay for the resources used or for the functions called out. But what does it mean?
Let’s say we have an application, which is used mostly during standard working hours (9-17). For the rest of the day, the application “sleeps”. With the traditional approach, we will pay for the whole day all the same, even if no one has used the application for almost 16 hours. In a case like this, we can save up a lot with serverless. Why? Because when our service is deployed as a function, we pay only for each execution or for the execution time. The cost is tied to actual usage.
What else can functions give us? For once, they are extremely scalable. Depending on the traffic, the functions scale up to a level that will allow for handling of all the requests. They are also highly available, so we don’t have to worry about service availability.
That’s the theory – what about practice? Let’s make a quick serverless for beginners project to really get you started!
Serverless application development frameworks
We’re going to use the Serverless Framework, one of the most popular tools for building serverless applications. It is an open source solution and you can find it on GitHub. This framework supports a lot of providers such as AWS, GCP, Azure, OpenWhisk and many others. It also supports different languages such as Node.js, C#, Java, Go, Python etc. With a large community around it as well as impressive popularity, it’s definitely worth a try.
Let’s create our REST API!
For the purpose of this article, we’re going to create a simple Doge-themed (wow!) REST API. It will be a CRUD application, nothing complicated. Let’s get it going.
Installing Serverless Framework
First, we need to install it on the computer with the following command. We need it to be global so we can use it from anywhere on our computer.
Creating Node.js Application with Serverless Framework Template
In the command line, let’s move to the directory when we want to have source code and execute the following command:
In this command, we need to use the –template flag to specify runtime language in which we would like to write a service, –path to specify a directory in which our template will be created and –name to give a name to the function. In the douge-app directory, we should have two files:
- handler.js – it is your lambda function declaration. This function returns a body with “Go Serverless v1.0! Your function executed successfully!” message.
- serverless.yml – it contains the configuration of our function. In this article, we will use only three sections:
- provider – to specify which vendor service we would like to use (we also specify a region, runtime, stage etc.),
- functions – here we specify all the functions provided by our service,
- resources – to declare all the resources which we need to run with our functions. Here you can find more information about this file.
Update the serverless.yml file
Let’s move to the serverless.yml file and change it in the following way:
We just specified which provider will host our function. In this case, we’re going to use AWS. We also defined the version of Node.js and provider region where the function will be deployed. In the functions section, for now we only add a getDoge. We need to define where our handler is by defining its location. In events, we specify a HTTP method and the path to our endpoint.
Next, we need to move the file handler.js to a new folder called api and rename it to doges.js. For now, let’s only mock our function and return the hardcoded result to check if our function really works. Here is the implementation:
Now we can try to deploy our function. But make sure that you are logged into your AWS account in your console. If you aren’t, take the following steps:
- Go to the AWS console.
- Select the Identity and Access Management (IAM) service.
- On the left sidebar, go to Users. You should see a list of users. if you haven’t got any, just click the “Add user” button.
- Set the name of your user. In this case, it is simply serverless. As an access type, select Programmatic access.
- In the permission section, select AdministratorAccess and AWSLambdaVPCAccessExecutionRole, and then go to the next stage.
- Now, you are in the tags section, from there choose the Create user option.
At this point, you should have user credentials. You will use it with the following command to authenticate in AWS and deploy your function:
Let’s try if you are able to deploy a function. Just execute the command below:
In the terminal, you should see output like this:
In the AWS response, you can find an URL to your function. In this case, we get this:
When you send a GET request to this endpoint, you should see the following response:
Great – your first function works! Let’s go deeper.
Adding the database
Ok, we are able to get something hard-coded using our function, but the better idea would be to store data and retrieve it from a database. Let’s configure it.
We’re going to use DynamoDB. It is a NoSQL database which supports the key-value document data structure. It is offered by Amazon. Since we want to stay with one provider, we’re going to use it in our application. Thanks to the Serverless Framework, we don’t have to create a database on our own. We can simply use a serverless.yml file.
First, we need to update our provider section. We will add an iamRoleStatements section to create a role for our function because every lambda needs to have permissions to interact with other resources within your account. These permissions are set in this section. Our provider section should look like this:
Next, we need to create a table, where we’re going to store our doges.
You should note that in the provider section we define an environment variable called DOGE_TABLE. This variable defines the table name for a specific stage. Instead of hardcoding a table name in our configuration file and then in our code, we can define it there and call it in our configuration and code.
With the database configured, we can now update our GET endpoint and add another one (POST) to be able to add new doges to the database.
Let’s add a POST endpoint to add new doges. Before we can do it, let’s execute the following command:
It will install a few libraries, which we’re going to use in our code. Let’s now take a look at our implementation. First, we need to add a new export in the /api/doge.js file.
We need to add a new endpoint definition in the serverless.yml file too:
Now, if we make a POST request to our API, we should get the following response:
Since we can now add a doge, it would be nice if we could also retrieve all or specific doges from our database by id. We need to update our existing GET endpoint and also add a new one. Let’s update our api/doge.js file like this:
Now, let’s update the serverless.yml file:
And that’s all. Now, we have two different methods to retrieve our doges! 😀
What if we wanted to use Express.js?
Looking at the example above, you might start thinking: “is it the only way to create a REST API on serverless? What if I had an Express application, and now I would like to host in something like AWS Lambda? Is it possible?”. My answer is.. of course! And I will show you just how you can achieve it!
We’re going to need to install the serverless-http package and add it to our existing code. Just import it like this: const serverless = require(‘serverless-http’); export our app wrapped in module.exports.handler = serverless(app). The last thing to do will be setting up your serverless.yml file.
Let’s take a look at the example below. It is an Express application, but with a couple modifications:
Compared to the previous configuration, we just replaced a functions section with the code above. All the other configurations remain the same. It is enough to be able to deploy your application as a lambda.
How does this configuration work? We’re simply forwarding all the traffic to our application and letting Express handle all the requests with its routing. It is very convenient, because we don’t need to define all the routes in our configuration. What’s more, we are able to use all the features that Express gives us. For example, we can add error-handling or authentication middleware. We now have a fully functional Express application hosted serverless.
Serverless app development – summary
I hope that this little introduction will help you with your first steps in the world of serverless. As you have just witnessed, creating this kind of application is very similar to a common Express application. You can choose two approaches: creating each function separately or by using a framework. You can also combine your solution with the services of other providers. Out of the box, you get plenty of very useful tools, which speed up your serverless application development.
Personally, I suggest you try this by yourself. Perhaps, you have an idea for an application, and you need a cheap solution to host it? Or maybe you can see where you could use it in your existing project? Practice makes perfect!