Since Netlify is well known for hosting static sites that don't come with a backend, serverless functions help fill some of those gaps. In this article, we will walk through creating a serverless/lambda function, running and testing it locally, and deploying it to Netlify.

Table of Contents

Serverless functions is actually the more generic term. Serverless is a misnomer, however, as it doesn't mean there is no server at all.

It simply means you, the developer, don't have to worry about the server.You don't have to create a Node server, for example, because the host takes care of all of that for you. All you have to worry about is writing the actual functionality with no regards for infrastructure, versioning, etc.

The word Lambda is a proper noun referring to the type of serverless functions that are hosted on Amazon's AWS cloud platform. They were one of the very first ones to support/implement serverless functions, and this is the type of serverless functions that Netlify supports.

In this article serverless functions and Lambda Functions will refer to the functions that we create and host in Netlify.

For this demo, I am going to start with a basic Gatsby app. You don't have to use Gatsby yourself (it really doesn't matter what kind of site you us), but if you want to get caught up with the same starter, go back and check out Deploying Your First Gatsby Site to Netlify.

For reference, when running mine, it just looks like this.

To get started, we need to create a folder that contains all of our Lambda Functions. It doesn't really matter where you put the folder or what you call it, but I'm going to put mine in the root of my app and call it functions.

For reference, there will be a 1:1 relationship between the files in this folder and the functions that get deployed. In other words, we will create a new JavaScript file for each function we host.
So, let's create a "test.js" file inside of the functions directory and get started writing some code. Here's the basic boilerplate code for a Lambda Function.

test.js

exports.handler=function(event, context, callback){}

Each function takes in three parameters event, context, and callback.

event : where we can retrieve post data, headers

context : information about the context in which the function was called, like certain user information

callback : a function that we call to return a response to the user

The first parameter that the callback function takes is an error, which is null if there is no error. If the error is present, it will be respected and handled back to the user, but if is is null, the second parameter gets returned to the user.

Free Node eBook

Build your first Node apps and learn server-side JavaScript.

📧

Thank you!

You have successfully joined the Scotchy super duper web dev awesome mailing list.

Here's a screenshot of my file structure, and a simple Hello World Lambda Function. In this example, I immediately call the callback function with no error and a return data with status of 200 and body of "Hello World".

Now that we've created a Hello World function, we need to be able to run it. To do this, we will use the "netlify-lambda" package. To install, run the following command.

npminstall netlify-lambda

With that package installed, the docs tell use to use the following command to run our functions locally, where <functions_directory> refers to the directory where we have written our source code.

netlify-lambda serve <functions_directory>

However, I wasn't able to run this command directly, so I created an alias in the package.json file, "start:lambda" to use NPM to run this command.

The last thing we need to do before we can run locally is to create a configuration file that tells Netlify where to serve our functions from. I want to be specific here, this is not the directory where we write our source code. In fact, our source code will go through a build process, and the built assets will be put in the folder that we specify. So, create a Netlify.toml file in the root of your directory that looks like this.

This tells Netlify that when our functions are built, put the built assets in a directory called "lambda".

Now, run the npm script we defined above. Notice in the screenshot that I tried to run this command once before creating the Netlify.toml and the command failed. You have to have your Netlify.toml file created before you can run locally.

Ok, now we've actually got something running. From here, I'm going to open up an app called Postman (go download and install it if you haven't already… trust me!!) to make test calls to the function (think a GUI for curl requests). With Postman open, I'll make a call to "localhost:9000", where lambda functions run by default locally. After making the request, I get a successful response.

We've got Hello World working, so let's take it one step further. I want to give an example of extracting the post body, returning a JSON object instead of a string, and conditionally returning an error. So, I'm going to expect that calls to this function pass in an object with a name property like this.

{"name":"James"}

To retrieve this data, originally, I thought I would just grab the body property off of the event parameter, and then the name parameter off of that...BUT, I was wrong. The body parameter is actually a string instead of an actual JSON object, so first I need to parse that JSON string into an object like this.

const parsedBody =JSON.parse(event.body);

Using ES6, I can take this one step further and grab the name property off of the parsedBody by using destructuring.

const{ name }=JSON.parse(event.body);

For demo purposes, I'm going to say if the name is "James" it's a good request, otherwise, it's a bad request and return data or error appropriately. If the name is "James", I want to return a json object with a msg property. When we return JSON objects, they need to be "stringified" because the body parameter will always be a string that gets returned. Will look something like this.

So far, we've just run our Lambda Function locally using the serve command. However, in production, we will need to run the build command, which will create the built assets that Netlify will serve up for. For this reason, I am going to create another script alias in the package.json file for building.

In Netlify, you only get one command to run when Continuous Deployment kicks in and grabs your latest code from Github. However, since I also need to build my Gatsby app, we will need two commands, one to build Gatsby and one to build your functions.

To accomplish this, I also added a prod script which will allows me to run both of theses commands sequentially.

"prod":"npm run build; npm run build:lambda",

Keep in mind, if you're not using Gatsby you may have an alternative build command or not need one at all.

The last thing we need to do before deploying is update the Netlify.toml file. This configuration file is read by Netlify when Continuous Deployment is triggered. In this file, we can tell Netlify to run our newly created "prod" command. Configurations in this file will override existing configurations set in the Netlify UI.

After checking these updates in and pushing to my Github repository, a new build will start that you can monitor in the Deployments tab. If you click on the deployment, you can view the logs. In the screenshot below, you can see our commands being run.

After the deployment has finished, you can navigate to the Functions tab. Since we actually deployed a function, you should notice your function listed in the dashboard (test.js below).

That's it, you should be ready to go. Keep in mind, you can be completely creative with your functions...they can do almost anything. Send an email, save data to a DB, make an API call… whatever you want. With functions under your belt, you can focus a lot on your front end (assuming you're using a static site generator like Gatsby), and fill in your backend needs using Lambda Functions or something like Firebase.

Would love to hear in the comments about the projects you guys are working on and how working with Netlify has been for you. Feel free to comment below or reach out to me on twitter, @jamesQquick.

James has a true passion for Web Development, Tooling, and Design. He follows the latest blogs, speaks at community events, and participates in Hackathons. James spent three years at Microsoft as a Technical Evangelist in New York City and Miami and is currently working at FedEx Services in Memphis as a Full-Stack Web Developer. He considers himself to be a "Social Developer" because of his love for working with people, and in his spare time, plays in weekly lunch basketball games, trains for half marathons, and solves a Rubik's cube in under two minutes.

James has a true passion for Web Development, Tooling, and Design. He follows the latest blogs, speaks at community events, and participates in Hackathons. James spent three years at Microsoft as a Technical Evangelist in New York City and Miami and is currently working at FedEx Services in Memphis as a Full-Stack Web Developer. He considers himself to be a "Social Developer" because of his love for working with people, and in his spare time, plays in weekly lunch basketball games, trains for half marathons, and solves a Rubik's cube in under two minutes.