DEV Community

Cover image for Running a serverless API using Netlify Functions
Adam Goth
Adam Goth

Posted on

Running a serverless API using Netlify Functions

Over the last few years, serverless applications have been growing in popularity. There are many use cases in which a serverless solution is more practical and more convenient than the traditional server solution. In this post, we'll look at setting up a serverless Express.js API using Netlify functions.


Before we dive into the code for this demo application, let's talk about a few concepts at a high-level.


"Serverless" is a term that is used for what can generally be thought of as a method of providing backend services on an as-used basis. Rather than setting up specific infrastructure, or a server, to provide the backend services, you can utilize a "serverless" provider to handle this functionality instead. This was first popularized by AWS Lambda but is now a service offered by many other companies as well, including the one we'll be looking at today, Netlify.

AWS Lambda

As mentioned above, AWS Lambda is the most popular provider of serverless computing. Here's how AWS Lamba describes itself in its own words:

AWS Lambda lets you run code without provisioning or managing servers. You pay only for the compute time you consume.

With Lambda, you can run code for virtually any type of application or backend service - all with zero administration. Just upload your code and Lambda takes care of everything required to run and scale your code with high availability. You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app.

As great as this sounds (and it really is great), setting up an AWS lambda function can be a tedious process, requiring quite a bit of configuration that can be easily confusing to someone is who new to serverless functions. If you're curious to see for yourself, here's an example tutorial directly from the AWS docs. But not to worry, that's why we're here to talk about Netlify Functions.

Netlify Functions

Netlify Functions greatly simplifies the process for running serverless functions. Using Netlify Functions, we can simply write our lambda function and drop it into the functions folder of our Netlify-hosted application. Behind the scenes, Netlify handles the interaction with AWS for us. We don't even need an AWS account. Every Netlify account is set up for this feature out of the box. There's no setup, servers, or ops required.

Let's see what this looks like in code.

The application

The code for this demo can be found here. Since the purpose of this post is to show how to set up a serverless API, rather than do anything specific with the API, this particular demo application will serve up an extremely basic API with two endpoints that don't do much. I will assume the reader has some basic familiarity with Express.js and Node as we will be using these to build the API.

If we take a look at our package dependencies, we have just five packages:

nodemon is used to automatically restart our server while we're working on it in development

express gives us our API framework

body-parser is middleware that allows us the parse our request bodies

serverless-http allows us to wrap our API for serverless use

netlify-lambda is a tool that helps us build our application code so that it can be consumed correctly by Netlify using Netlify Functions

The other thing to note in the package.json file are the two scripts. We have "start": "nodemon server-local.js" which is used for development, and "build": "netlify-lambda build express" which is used to build and deploy.

  "scripts": {
    "build": "netlify-lambda build express",
    "start": "nodemon server-local.js"
Enter fullscreen mode Exit fullscreen mode

The start script is fairly straight forward, it will just execute our server-local.js file which in turn is calling express/server.js. This works for local development, but we need to do additional work in our build script for the application to work as a serverless function once deployed to Netlify. In the build script, we call netlify-lambda build which takes a source folder as an argument (express in our case) and outputs it to a built folder. The built folder is where Netlify will look for our serverless functions. We have a couple of options for how we specify this. We could specify the designated folder within Netlify's application settings using Netlify's web app, or within our application code, we can specify the designated folder with a netlify.toml configuration file. In our case, we'll use a configuration file that lives in our root directory that looks like this:

// netlify.toml

  command = "npm install && npm run build"
  functions = "functions"
Enter fullscreen mode Exit fullscreen mode

With our scripts and build configuration accounted for, let's take a look at the core of the application.

The core of the application lives in the express/server.js file, and in our case, is just 29 lines.

"use strict"
const express = require("express")
const serverless = require("serverless-http")
const app = express()
const bodyParser = require("body-parser")
const router = express.Router()

app.use("/.netlify/functions/server", router) // path must route to lambda
app.use("/", router)

router.get("/", (req, res) => {
  res.writeHead(200, { "Content-Type": "text/html" })
  res.write("<h1>Up and running</h1>")
})"/doSomething", async (req, res) => {
  try {
    // maybe do some database interaction or third-party API call here!
    res.status(200).send({ data: "success" })
  } catch (err) {
    res.status(400).send({ error: "bad request" })

module.exports = app
module.exports.handler = serverless(app)
Enter fullscreen mode Exit fullscreen mode

If you've ever worked with Express.js, this should look pretty familiar to you. We have two endpoints, one GET endpoint at / and one POST endpoint at /doSomething.

These endpoints don't do much, but you could do just about anything you would normally do with GET or POST endpoints here. Hit a third-party API, connect to a database, fire off some sort of transaction, etc.

The two lines in the application that are specific to using Netlify's serverless functions are line 9 and line 29.

As we specified in our netlify.toml configuration file, our function code is going to live at ./netlify/functions/server. So we will tell our express app on line 9 to use our router object anytime a request is sent to this server.

app.use("/.netlify/functions/server", router)
Enter fullscreen mode Exit fullscreen mode

Lastly, on line 29, we will utilize the serverless-http package to wrap our application up for serverless use. This means our application can work as expected without any HTTP server, ports, or sockets.

module.exports.handler = serverless(app)
Enter fullscreen mode Exit fullscreen mode

With that, the application is all set to deploy to Netlify. If you've never deployed on Netlify before, you'll be amazed at how simple it is. This post won't go into details but it isn't much more than authenticating your GitHub account and selecting the repo and branch to deploy. Once the application is deployed, you can start accessing the endpoints we created at <your site URL>/.netlify/functions/server/<your endpoint>. We now have a basic yet fully-functioning API, without having to run or provision a dedicated and separate server!

Wrapping up

Hopefully you were able to follow along in creating this Netlify serverless function. Serverless computing is still a developing and evolving technology but its popularity continues to grow as more developers find it more suitable to their needs than traditional server applications.

The particular use case that led me to using Netlify functions is that I needed to make a third-party API call from my client application that required a private API key in the header. With just client-side code, there is no good way to keep your private API key private. I decided I needed a server to proxy the request through, but I didn't want to create and dedicate an entire server just to pass one small API request through. So this ended up being a perfect solution. Now that I know how convenient and simple this can be, I will be looking for more opportunities to utilize Netlify Functions.

For more technical information regarding the usage and implementation of Netlify Functions, be sure to visit the docs.

If you enjoyed this post or found it useful, please consider sharing it on Twitter.

If you want to stay updated on new posts, follow me on Twitter.

If you have any questions, comments, or just want to say hello, send me a message.

Thanks for reading!

Top comments (2)

rajani169 profile image

hey your post was really helpful but I'm stuck somewhere in 3rd party api calls. can you plz help me out

rajani169 profile image

actually post call is successful but the third party api calls are not working