Serverless Lambda functions on Netlify

AWS’s serverless Lambda functions open a world of possibilities for running on-demand, server-side code without having to run a dedicated server. However, managing service discovery, configuring API gateways, and coordinating deployments between your app and your serverless functions can quickly become overwhelming.

Netlify lets you deploy serverless Lambda functions without an AWS account, and with function management handled directly within Netlify. Your serverless functions are version-controlled, built, and deployed along with the rest of your Netlify site, and we will automatically handle service discovery through our built-in API gateway. This eliminates overhead and brings the power of Deploy Previews and rollbacks to your serverless functions.

All Netlify sites include 125,000 serverless function requests per month, and 100 hours of run time per month. Above that, billing scales with your usage.

Currently, you can deploy serverless functions built with JavaScript and Go.

This document will help you get started with Functions. Explore real-world serverless function code examples and tutorials to get inspired. Visit our Community forum to join the conversation about Functions.

Configuring the functions folder

To get started, designate a directory in your repository where Netlify can find your serverless functions. Netlify will access this directory during every deploy, zipping and deploying each supported code file as a serverless Lambda function on AWS. (Note that files in subdirectories will be ignored.)

In the Netlify web interface, go to Settings > Functions and enter a path to the directory in your repository where your serverless functions will be stored. You can also set this by adding a functions field to your netlify.toml file. (Settings in netlify.toml override settings in the web interface.)

The path is relative to the root of the repository, and is accessed by Netlify after running your build command. This has the following implications:

  • You can use your preferred workflow and tools for developing your serverless functions, then compile at build time to single files in the designated functions directory. (We’ve even made a tool to help you with this.)
  • You can access Netlify environment variables to inject API keys or other information you don’t want to store in your repository.
  • Though we process the files in the functions directory after running your build command, the directory is not visible over the web unless you place it in your site’s publish directory (not recommended).
  • Because the functions are deployed after the build, deploying serverless functions via this method requires continuous deployment. Alternatively, you can deploy serverless functions manually using Netlify CLI.

JavaScript Lambda functions

To add a serverless Lambda function to your project functions directory, create a JavaScript file which exports a handler method.

The name of the file (without the .js extension) determines the name of the serverless function endpoint. On deployment, each serverless function can be called from an address relative to the deployed site root: /.netlify/functions/{function_name}. You can also set a serverless function to be triggered by certain Netlify events.

The handler method

Each JavaScript file to be deployed as a serverless Lambda function must export a handler method with the following general syntax:

exports.handler = function(event, context, callback) {
    // your server-side functionality
}

Netlify provides the event and context parameters when the serverless function is invoked. You provide the callback parameter, which is optional, but recommended.

When you call a serverless function’s endpoint, the handler receives an event object similar to what you would receive from the AWS API Gateway:

{
    "path": "Path parameter",
    "httpMethod": "Incoming request's method name"
    "headers": {Incoming request headers}
    "queryStringParameters": {query string parameters }
    "body": "A JSON string of the request payload."
    "isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encode"
}

The context parameter includes information about the context in which the serverless function was called, like certain Identity user information, for example.

The callback works much like the same parameter in an AWS Lambda function. Your handler should use the callback to return either an error (as the first parameter) or a response object, such as:

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

Here’s a simple example serverless function, hello.js:

exports.handler = function(event, context, callback) {
    callback(null, {
    statusCode: 200,
    body: "Hello, World"
    });
}

This serverless function would be called from your site at /.netlify/functions/hello, and on success, would return the 200 status code and the string, “Hello, World”.

JavaScript Runtime Settings

By default, Netlify uses Node.js 8.10 as runtime for all new serverless functions written in JavaScript. You can override this by specifying the desired runtime with an environment variable.

For example, to use Node.js 10 for all future serverless functions deployed, set the variable AWS_LAMBDA_JS_RUNTIME with the value nodejs10.x.

This variable accepts any valid AWS Lambda runtime name for JavaScript.

Tools for building JavaScript functions

We’ve made a few tools to help with writing, testing, and deploying your serverless JavaScript functions on Netlify.

Netlify Lambda CLI

Available on npm, netlify-lambda allows you to run your serverless functions locally for testing, and prepare them for deployment with a basic webpack/Babel setup. This way you can write your serverless functions how you like, with modern JavaScript, shared modules between scripts, etc., then have them compiled to a single file per function, ready for use in any Node runtime.

To use netlify-lambda in your project:

  1. Install it in your project directory using npm install netlify-lambda or yarn add netlify-lambda.
  2. Include a netlify.toml file in the root of your project, specifying the location of your functions folder:

    [build]
      functions = "<path/to/your/folder>"
    
  3. Put the source files for your serverless Lambda functions in another folder inside your project. This will be the <source-folder> in your netlify-lambda commands.

To run your serverless Lambda functions locally, enter the following command:

netlify-lambda serve <source-folder>

This will start a local dev server and a file watcher for the specified folder. Requests to http://localhost:9000/hello will route to <source-folder>/hello.js.

To prepare your serverless functions for deployment, run:

netlify-lambda build <source-folder>

This will run a single build of the serverless functions in the source folder, transpiling and saving each as a single file in the functions folder you specified in your netlify.toml file. You can include this command with your regular build tool for continuous deployment.

Create React App Lambda

Based on the popular Create React App, Create React App Lambda integrates Netlify Lambda CLI functionality into a basic app you can use as a reference or starting point.

It includes:

  • a src/lambda file for storing your serverless function files
  • a netlify.toml file to specify the functions folder, as well as a combined app+functions build command for instant deployment to Netlify
  • netlify-server CLI tool, with the yarn start:lambda command to run your serverless functions locally
  • built-in proxy redirect from /.netlify/functions/* to your local functions server, meaning in-app serverless function calls will work locally exactly as they do on Netlify

You can visit the repo for more details, or you can quickly deploy a version of your own with the click of a button:

Deploy to Netlify

Go Lambda Functions

AWS Lambda supports compiled Go binaries to run as serverless functions. You can precompile them yourself, or Netlify can compile them for you as part of our continuous deployment.

The handler method

The official AWS repository has very good examples to learn how to create serverless functions with Go. This section walks you through the steps to create a serverless function that Netlify can deploy and serve with a dedicated endpoint.

Each Go file to be deployed as a serverless Lambda function must include a handler function to receive events from AWS API Gateway:

func handler(ctx context.Context, request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
  # Your server-side functionality
}

The ctx parameter includes information about the context in which the function was called, like certain Identity user information, for example.

The response must be compatible with the AWS API Gateway response:

return &events.APIGatewayProxyResponse{
		StatusCode: 200,
		Body:       "Hello, World",
	}, nil

Here’s a complete example function hello.go:

package main

import (
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
	return &events.APIGatewayProxyResponse{
		StatusCode: 200,
		Body:       "Hello, World",
	}, nil
}

func main() {
	// Make the handler available for Remote Procedure Call by AWS Lambda
	lambda.Start(handler)
}

This function would be called from your site at /.netlify/functions/hello, and on success, would return the 200 status code and the string, “Hello, World”.

Accessing the ClientContext

Netlify can add extra request information to a serverless function call using AWS Lambda’s ClientContext. To access this information, you need to use a handler definition that includes a Go Context struct. This object can be transformed into a LambdaContext to access the ClientContext:

func handler(ctx context.Context, request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
	lc, ok := lambdacontext.FromContext(ctx)
	if !ok {
		return &events.APIGatewayProxyResponse{
			StatusCode: 503,
			Body:       "Something went wrong :(",
		}, nil
	}

	cc := lc.ClientContext

	return &events.APIGatewayProxyResponse{
		StatusCode: 200,
		Body:       "Hello, " + cc.Client.AppTitle,
	}, nil
}

Building Go functions with Netlify’s Continuous Deployment

Netlify can build your source Go functions into AWS Lambda compatible binaries. The Go version used in the deployment pipeline is determined by your site’s selected build image.

Before building your Go source, Netlify needs to know the expected Go import path for your project. Use the GO_IMPORT_PATH environment variable to set the right import path. You can do this in the Netlify UI at Settings > Build & deploy > Environment > Environment variables, or in your netlify.toml file. The path value should point to your source repository on your Git provider, for example github.com/netlify/aws-lambda-go-example.

Once the Go import path is set, go get will work as expected, and you can also use any dependency management tool to download dependencies for your project.

You can see a full example in this repository:
https://github.com/netlify/aws-lambda-go-example.

Event-triggered functions

You can trigger serverless function calls when certain Netlify events happen, like when a deploy completes successfully. The following events are currently available:

  • deploy-building: Triggered when Netlify starts building a site for deployment.
  • deploy-succeeded: Triggered when Netlify finishes deploying a site.
  • deploy-failed: Triggered when Netlify fails to deploy a site.
  • deploy-locked: Triggered when a deploy is locked in production and Netlify stops autopublishing deploys.
  • deploy-unlocked: Triggered when a deploy is unlocked from production and Netlify resumes autopublishing deploys.
  • split-test-activated: Triggered when a split test is activated.
  • split-test-deactivated: Triggered when a split test is deactivated.
  • split-test-modified: Triggered when a split test’s settings change.
  • submission-created: Triggered when a form submission is verified for your site.
  • identity-validate: Triggered when an Identity user tries to sign up via Identity.
  • identity-signup: Triggered when an Identity user signs up via Netlify Identity.
  • identity-login: Triggered when an Identity user logs in via Netlify Identity.

An event-triggered function is built like any other, as described above. To make it trigger on an event, match the name of the function file to the name of the event. For example, to trigger a function on deploy-succeeded events, name the function file deploy-succeeded.js.

Event function payloads

The request body for these functions is a JSON document that includes information about the associated site, as well as the object that triggered the event, such as a deploy, split test, or verified form submission. All payloads have this shape:

{
  "payload": {
    # information about the object that triggered the event
  },
  "site": {
    # information about the associated site
  }
}

Event functions signature

To prevent external requests to event functions, Netlify generates a JSON web signature (JWS) for each event triggered by our platform, and verifies that the signature is correct before invoking an associated event function.

Identity and Functions

If you have Identity enabled on your site, your serverless functions get access to the Identity instance and to Identity user claims in the context object. You can also trigger serverless functions via Identity events.

Identity and clientContext

If an Identity service is active for a site, serverless functions running on that site have access to an identity and a user object in the clientContext. You can access the client context like this:

export function(event, context, callback) {
  const {identity, user} = context.clientContext;
  // Do stuff...
}

The user object is present if the function request has an Authorization: Bearer <token> header with a valid JWT from the Identity instance. In this case the object will contain the decoded claims.

The identity object has url and token attributes. The URL is the endpoint for the underlying GoTrue API powering the Identity service. The token attribute is a short-lived admin token that can be used to make requests as an admin to the GoTrue API.

Identity event functions

You can trigger serverless function calls when certain Identity events happen, like when a user signs up. The following events are currently available:

  • identity-validate: Triggered when an Identity user tries to sign up via Identity.
  • identity-signup: Triggered when an Identity user signs up via Netlify Identity.
  • identity-login: Triggered when an Identity user logs in via Netlify Identity

To set a serverless function to trigger on one of these events, match the name of the function file to the name of the event. For example, to trigger a serverless function on identity-login events, name the function file identity-login.js.

If you return a status other than 200 or 204 from one of these event functions, the signup or login will be blocked.

The payload in the body of an Identity event function looks like:

{
  "event": "login|signup|validate",
  "user": {
    # an Identity user object
  }
}

If your serverless function returns a 200, you can also return a JSON object with new user_metadata or app_metadata for the Identity user. For example, if you return:

{"app_metadata": {"roles": ["admin"]}}

The value of the Identity user’s app metadata will be replaced with the above.

Managing your functions

Serverless Lambda functions deployed via Netlify are immutable. This means that an update to a function on your production branch won’t change the version that was deployed in a branch deploy, or in a Deploy Preview. You can access all versions of your serverless functions in the Netlify web interface, under the Functions tab.

By default, the list displays the serverless functions in the current production deploy. To see functions on another deploy, you can use the dropdown at the top of the list. You can start typing to jump to a particular branch, or find a Deploy Preview by number.

Function logs

Selecting a serverless function from the list on the Functions page will open the log for that function. Netlify displays a running log for the last hour of activity, including:

  • Start of each invocation
  • Any console.log() statements you include in your function code

Usage and Billing

You can check your Functions service usage under Settings > Functions > Overview > Usage. This shows your current usage level and tracks the following metrics:

  • Requests: This counts each time a serverless function endpoint is called on your site during the current billing period.
  • Run time: This calculates the combined compute time of all serverless function requests during the current billing period.

Functions pricing scales with usage. When usage reaches a level limit, the site will automatically upgrade to the next level or package.

Changing levels

Any team member with the ability to change settings on your site can also change levels for services on that site.

To do this, go to Settings > Functions > Lambda Functions > Usage, and select Change level. Add-on fees will be prorated and charged at the end of the billing cycle, to the team’s payment method.

Custom deployment options

By default all serverless functions are deployed to AWS Lambda in their us-east-1 region, with 128MB of memory and a 10 second execution limit.

If you want to deploy your serverless functions on different AWS regions, tweak memory or execution time limits, or deploy serverless functions onto your own AWS account (in order to integrate with other AWS services on your account), please contact sales.


Notice something is incorrect or outdated?

First off, great catch! We appreciate your discovery and want to ensure it gets addressed immediately. Please let us know here.



Want to have a conversation?

Visit the Netlify Community to discuss ideas and questions with your fellow Netlify users.

Want to get started quick?