Lambda functions on Netlify

AWS 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 functions can quickly become overwhelming.

Netlify lets you deploy Lambda functions without an AWS account, and with function management handled directly within Netlify. Your 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 functions.

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

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

Configuring the functions folder

To get started, designate a directory in your repository where Netlify can find your functions. Netlify will access this directory during every deploy, zipping and deploying each supported code file as a 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 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 base 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 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 build 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 functions are deployed after the build, sites without continuous deployment will not work with Netlify Functions.

JavaScript Lambda functions

To add a 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 function endpoint. On deployment, each Lambda function can be called from an address relative to the deployed site root: /.netlify/functions/{function_name}. You can also set a function to be triggered by certain Netlify events.

The handler method

Each JavaScript file to be deployed as a 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 function is invoked. You provide the callback parameter, which is optional, but recommended.

When you call a 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 function was called, like certain 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 function hello.js:

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

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”.

JavaScript Runtime Settings

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

For example, to use Node.js 6.10 for all future Lambda functions deployed, set the variable AWS_LAMBDA_JS_RUNTIME with the value nodejs6.10 in your build context.

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 JavaScript Lambda functions on Netlify.

Netlify Lambda CLI

Available on npm, netlify-lambda allows you to serve your functions locally for testing, and prepare them for deployment with a simple webpack/Babel setup. This way you can write your 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 base of your project, specifying the location of your functions folder:

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

To serve your Lambda functions locally, run:

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 functions for deployment, run:

netlify-lambda build <source-folder>

This will run a single build of the 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 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 serve your functions locally
  • built-in proxy redirect from /.netlify/functions/* to your local function server, meaning in-app 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 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 functions with Go. This section walks you through the steps to create a function that Netlify can deploy and serve with a dedicated endpoint.

Each Go file to be deployed as a 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 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 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. Our deployment pipeline supports the most recent version of Go, 1.10.

Before building your Go source, Netlify needs to know the expected Go import path for your project. Use the GO_IMPORT_PATH build environment variable to set the right import path. You can do this in the Netlify UI at Settings > Build & deploy > Continuous Deployment > Build 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 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 posted to your site. Available on sites with Forms Pro.
  • identity-validate: Triggered when a user tries to sign up via Identity.
  • identity-signup: Triggered when a user signs up via Netlify Identity.
  • identity-login: Triggered when a 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 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 functions get access to the Identity instance and to user claims in the context object. You can also trigger functions via Identity events.

Identity and clientContext

If an Identity service is active for a site, 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 function calls when certain Identity events happen, like when a user signs up. The following events are currently available:

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

To set a 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 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": {
    # a user object
  }
}

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

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

The value fo the users’s app metadata will be replaced with the above.

Managing your functions

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 functions in the Netlify web interface, under the Functions tab.

By default, the list displays 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 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 > Lambda functions > Usage. This shows your current plan and tracks the following metrics:

  • Requests: This counts each time a function endpoint is called on your site during the current billing period. Functions Free includes up to 125,000 requests per month, and Functions Pro includes up to 2 million requests per month. Additional usage is charged in blocks of 1 million requests.

  • Run time: This calculates the combined compute time of all function requests during the current blling period. Functions Free includes up to 100 hours of run time per month, and Functions Pro includes up to 1000 hours per month. Additional usage is charged in blocks of 1000 hours.

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

Changing plans

Any user with the ability to change settings on your site can also change plans for services on that site.

To do this, go to Settings > Functions > Lambda Functions > Usage, and select Change plan. Plan fees will be prorated and charged at the end of the billing cycle, to the account of the site owner.

Custom deployment options

By default all 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 functions on different AWS regions, tweak memory or execution time limits, or deploy 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 eye! We appreciate your discovery and want to ensure it gets addressed immediately. Please let us know here.

Want to get started quick?