Skip to content

Lambda compatibility for Functions

Select your function language:

Before creating a TypeScript function, prepare your project by doing the following:

Terminal window
npm install @netlify/functions
  • Set up tsconfig.json. We recommend that you enable the properties esModuleInterop and verbatimModuleSyntax in your TypeScript configuration file for better compatibility. During the build process, Netlify automatically loads any tsconfig.json configuration files found in your functions directory, the repository root directory, or the base directory, if set.

Create function file

To add a serverless function to your project, create a TypeScript file in your functions directory following the instructions below for naming and coding your function. Netlify will access the functions directory during every build, preparing and deploying each supported code file as a function.

The default functions directory is YOUR_BASE_DIRECTORY/netlify/functions. You can optionally configure a custom functions directory.

Name your function

You can store your function file directly under the functions directory or in a subdirectory dedicated to the function. The function’s endpoint name is case-sensitive and determined by its filename or the name of its dedicated parent directory.

For example, to create a function with an endpoint name of hello, save the function file in one of the following ways:

  • netlify/functions/hello.ts
  • netlify/functions/hello/hello.ts
  • netlify/functions/hello/index.ts

These formats would deploy a synchronous function that can be called on the following endpoint: /.netlify/functions/hello. The endpoint is relative to the base URL of your site. Here are some example full endpoint URLs: yoursitename.netlify.app/.netlify/functions/hello for a site using the default Netlify subdomain or www.yourcustomdomain.com/.netlify/functions/hello for a site using a custom domain.

To create a background function, append the function name with -background. For example, to create a background function with an endpoint name of hello-background, save the function file in one of these ways:

  • netlify/functions/hello-background.ts
  • netlify/functions/hello-background/hello-background.ts
  • netlify/functions/hello-background/index.ts

These formats would deploy a background function that can be called on the following endpoint: /.netlify/functions/hello-background. The endpoint is relative to the base URL of your site. Here are some example full endpoint URLs: yoursitename.netlify.app/.netlify/functions/hello-background for a site using the default Netlify subdomain or www.yourcustomdomain.com/.netlify/functions/hello-background for a site using a custom domain.

Code your function

This section will help you learn how to write functions. It covers the syntax for synchronous functions, both buffered and streaming, as well as background functions.

Synchronous function format

To create a synchronous function, use the following general syntax in your TypeScript function file to export a handler method:

import type { Handler, HandlerEvent, HandlerContext } from "@netlify/functions";
const handler: Handler = async (event: HandlerEvent, context: HandlerContext) => {
// your server-side functionality
};
export { handler };

Import types before declaring the function.

  • If you import the Handler type as demonstrated in the previous code sample, the event and context arguments and the response are typed accordingly.
  • Alternatively, you can import the types HandlerEvent, HandlerContext, and HandlerResponse separately and use them to construct a handler function.

Netlify provides the event and context parameters when the function is invoked.

  • The event object received by the handler is similar to the following:

    {
    "path": "Path parameter (original URL encoding)",
    "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-encoded"
    }

    If you need to parse a multipart/form-data-encoded event.body, we recommend using busboy. To learn more, visit our blog article on processing multipart form data with Netlify Functions.

  • The context object received by the handler includes information about the context in which the function was called, like certain Identity user information, for example.

Here’s a basic example function, hello.ts:

ts
import type { Handler, HandlerEvent, HandlerContext } from "@netlify/functions";
const handler: Handler = async (event: HandlerEvent, context: HandlerContext) => {
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello World" }),
};
};
export { handler };
  • This function deploys to an endpoint at /.netlify/functions/hello relative to the base URL of your site.
  • A successful invocation returns the 200 status code and the string, “Hello, World”.

Synchronous functions can return a response object that includes the following information:

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
"body": "..."
}
  • Because async function code returns a promise, we recommend returning a response with at least an HTTP status code instead of allowing the function to time out. Using async in your function code doesn’t automatically designate a function as a background function.
Response streaming

This feature is in Beta.

Netlify Functions can stream data to clients as it becomes available, rather than returning a buffered payload at the end of the computation. This lets developers and frameworks create faster experiences by using streaming and partial hydration to get content and interactions in front of people as quickly as possible.

To stream a function’s response:

  • wrap your handler export with the stream decorator
  • return a ReadableStream as the body

Here’s a simplified example that you can use to test that your function response streams to the client:

import { stream } from "@netlify/functions";
export const handler = stream(async () => {
const encoder = new TextEncoder();
const formatter = new Intl.DateTimeFormat("en", { timeStyle: "medium" });
const body = new ReadableStream({
start(controller) {
controller.enqueue(encoder.encode("<html><body><ol>"));
let i = 0;
const timer = setInterval(() => {
controller.enqueue(
encoder.encode(
`<li>Hello at ${formatter.format(new Date())}</li>\n\n`
)
);
if (i++ >= 5) {
controller.enqueue(encoder.encode("</ol></body></html>"));
controller.close();
clearInterval(timer);
}
}, 1000);
}
});
return {
headers: {
"content-type": "text/html"
},
statusCode: 200,
body
};
});

For an extended example that demonstrates a more likely response streaming use case, consider this function:

import { stream } from "@netlify/functions";
export const handler = stream(async event => {
// Get the request from the request query string, or use a default
const pie =
event.queryStringParameters?.pie ??
"something inspired by a springtime garden";
// The response body returned from "fetch" is a "ReadableStream",
// so you can return it directly in your streaming response
const res = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
// Set this environment variable to your own key
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content:
"You are a baker. The user will ask you for a pie recipe. You will respond with the recipe. Use markdown to format your response"
},
// Use "slice" to limit the length of the input to 500 characters
{ role: "user", content: pie.slice(0, 500) }
],
// Use server-sent events to stream the response
stream: true
})
});
return {
headers: {
// This is the mimetype for server-sent events
"content-type": "text/event-stream"
},
statusCode: 200,
// Pipe the event stream from OpenAI to the client
body: res.body
};
});

When invoked this function sends a prompt to OpenAI and streams the response back to the client like a chatbot.

Keep the following limitations in mind when working with streaming functions:

  • 10 second execution limit. If the limit is reached, the response stops streaming.
  • 20 MB response size limit. Responses larger than 20 MB cannot be streamed.
  • Background Functions can’t stream responses.
  • On-demand Builders can’t stream responses.
  • Scheduled Functions can’t stream responses.

Background function format

This feature is in Beta and is available on Pro and Enterprise plans.

To create a background function, append the function name with -background. For example, netlify/functions/hello-background.ts or netlify/functions/hello-background/index.ts.

Background function syntax is similar to synchronous function syntax with a couple of key differences:

  • You will generally pass the function result to a destination other than the originating client.
  • Background functions don’t support response streaming because they don’t return responses.

Like the synchronous function format, each TypeScript file to be deployed as a background function must import types and export a handler method. As with synchronous function invocation, Netlify provides the event and context parameters when a background function is invoked. Although background functions rely on asynchronous invocation, they don’t require the use of async TypeScript syntax.

Here’s a simplified example background function that you can use to test that your function runs longer than 30 seconds, count-background.ts:

import type { BackgroundHandler, HandlerEvent, HandlerContext } from "@netlify/functions";
export const handler: BackgroundHandler = (event: HandlerEvent, context: HandlerContext) => {
const sleep = (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
(async () => {
for (let i = 0; i <= 60; i++) {
const date = new Date();
await sleep(1000);
console.log(date.toLocaleString(), i);
}
console.log("Done");
})();
};
  • This function deploys to an endpoint at /.netlify/functions/count-background relative to the base URL of your site.
  • When invoked, the function returns an initial 202 success response.
  • When successfully executed, the function logs numbers 1 through 60.

For an extended example that demonstrates a more likely background function use case, consider this send-pdf-background.ts function:

import { jsPDF } from "jspdf";
import mailgun from "mailgun-js";
import type { BackgroundHandler, HandlerEvent } from "@netlify/functions";
type Context = {
content: string;
destination: string;
};
const mg = mailgun({
apiKey: process.env.MAILGUN_API_KEY,
domain: process.env.MAILGUN_DOMAIN,
});
const handler: BackgroundHandler = async (event: HandlerEvent) => {
if (!event.body) {
return;
}
const { content, destination } = JSON.parse(event.body) as Context;
console.log(`Sending PDF report to ${destination}`);
const report = Buffer.from(
new jsPDF().text(content, 10, 10).output("arraybuffer")
);
const info = await mg.messages().send({
from: process.env.MAILGUN_SENDER,
to: destination,
subject: "Your report is ready!",
text: "Details in attached report PDF",
attachments: [
{
filename: `report-${new Date().toDateString()}.pdf`,
content: report,
contentType: "application/pdf",
},
],
});
console.log(`PDF report sent: %s`, info.id);
};
export { handler };
  • This background function deploys to an endpoint at /.netlify/functions/send-pdf-background relative to the base URL of your site.
  • When invoked, the function returns an initial 202 success response.
  • When successfully executed, a PDF report is generated and emailed as an attachment.

Environment variables

Netlify Functions have access to environment variables in the runtime environment. If you have the option to set specific scopes for your environment variables, the scope must include Functions to be available to functions during runtime.

You can also leverage build environment variables to configure how Netlify builds your functions. For example, you can use an environment variable to set the Node.js version.

Learn more about how to set and use environment variables with functions.

Manage dependencies

To optimize build performance, specify function dependencies in the top-level package.json file in the site’s base directory. Here’s an example of a recommended layout:

my-base-directory/
├─ package.json
├─ node_modules
└─ netlify/
└─ functions/
├─ hello.ts
└─ send-pdf-background.ts

With continuous deployment, Netlify automatically zips dependencies with your functions for deployment. To do this, Netlify’s build system installs your dependencies and parses each function file to note its dependencies. For each function, Netlify then pulls the required dependencies from the associated node_modules folder and zips them with the function file for deployment. For more details about how this bundling functionality works, visit the repository for the underlying module: @netlify/zip-it-and-ship-it.

If you’re using a Netlify configuration file to configure custom [functions] settings, note that the node_bundler value for TypeScript functions always overrides to esbuild.

Test locally

To streamline writing and testing your functions on Netlify, run a local development environment with Netlify Dev. This feature of Netlify CLI includes tools for local function development through a simulated Netlify production environment. The netlify dev command starts a framework server if a framework is detected and handles redirects, proxy rules, environment variables, and Netlify Functions.

To simulate Netlify Functions in a standalone server without the full overhead of Netlify Dev, serve functions locally with the netlify functions:serve CLI command (currently in beta). Then to debug functions, inspect the functions server process.

Because Netlify’s build system doesn’t perform type checking, we recommend that you type check locally with one of these options:

  • Use your code editor to type check during local development.
  • Use the official TypeScript compiler, running tsc --noEmit locally before committing the files.

Next steps

Push your function source files to your Git provider for continuous deployment where Netlify’s build system automatically detects, builds, and deploys your functions. For more control over the process, learn about other workflows for deploying your functions including custom builds with continuous deployment and manual deploys with the Netlify CLI or API.

Monitor function logs and metrics in the Netlify UI to observe and help troubleshoot your deployed functions.

Netlify function logs are found in the Netlify UI. You can also stream Netlify function logs to the console with the Netlify CLI.

Create function file

To add a serverless function to your project, create a JavaScript file in your functions directory following the instructions below for naming and coding your function. Netlify will access the functions directory during every build, preparing and deploying each supported code file as a function.

The default functions directory is YOUR_BASE_DIRECTORY/netlify/functions. You can optionally configure a custom functions directory.

Name your function

You can store your function file directly under the functions directory or in a subdirectory dedicated to the function. The function’s endpoint name is case-sensitive and determined by its filename or the name of its dedicated parent directory.

For example, to create a function with an endpoint name of hello, save the function file in one of the following ways:

  • netlify/functions/hello.js
  • netlify/functions/hello/hello.js
  • netlify/functions/hello/index.js

These formats would deploy a synchronous function that can be called on the following endpoint: /.netlify/functions/hello. The endpoint is relative to the base URL of your site. Here are some example full endpoint URLs: yoursitename.netlify.app/.netlify/functions/hello for a site using the default Netlify subdomain or www.yourcustomdomain.com/.netlify/functions/hello for a site using a custom domain.

To create a background function, append the function name with -background. For example, to create a background function with an endpoint name of hello-background, save the function file in one of these ways:

  • netlify/functions/hello-background.js
  • netlify/functions/hello-background/hello-background.js
  • netlify/functions/hello-background/index.js

These formats would deploy a background function that can be called on the following endpoint: /.netlify/functions/hello-background. The endpoint is relative to the base URL of your site. Here are some example full endpoint URLs: yoursitename.netlify.app/.netlify/functions/hello-background for a site using the default Netlify subdomain or www.yourcustomdomain.com/.netlify/functions/hello-background for a site using a custom domain.

Code your function

This section will help you learn how to write functions. It covers the syntax for synchronous functions, both buffered and streaming, as well as background functions.

Synchronous function format

To create a synchronous function, use the following general syntax in your JavaScript function file to export a handler method:

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

Netlify provides the event and context parameters when the function is invoked.

  • The event object received by the handler is similar to the following:

    {
    "path": "Path parameter (original URL encoding)",
    "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-encoded"
    }

    If you need to parse a multipart/form-data-encoded event.body, we recommend using busboy. To learn more, visit our blog article on processing multipart form data with Netlify Functions.

  • The context object received by the handler includes information about the context in which the function was called, like certain Identity user information, for example.

Here’s a basic example function, hello.js:

exports.handler = async function(event, context) {
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello World" })
};
};
  • This function deploys to an endpoint at /.netlify/functions/hello relative to the base URL of your site.
  • A successful invocation returns the 200 status code and the string, “Hello, World”.

Synchronous functions can return a response object that includes the following information:

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
"body": "..."
}
  • Because async function code returns a promise, we recommend returning a response with at least an HTTP status code instead of allowing the function to time out. Using async in your function code doesn’t automatically designate a function as a background function.
Response streaming

This feature is in Beta.

Netlify Functions can stream data to clients as it becomes available, rather than returning a buffered payload at the end of the computation. This lets developers and frameworks create faster experiences by using streaming and partial hydration to get content and interactions in front of people as quickly as possible.

To stream a function’s response:

  • wrap your handler export with the stream decorator
  • return a ReadableStream as the body

Here’s a simplified example that you can use to test that your function response streams to the client:

const { stream } = require("@netlify/functions");
exports.handler = stream(async () => {
const encoder = new TextEncoder();
const formatter = new Intl.DateTimeFormat("en", { timeStyle: "medium" });
const body = new ReadableStream({
start(controller) {
controller.enqueue(encoder.encode("<html><body><ol>"));
let i = 0;
const timer = setInterval(() => {
controller.enqueue(
encoder.encode(
`<li>Hello at ${formatter.format(new Date())}</li>\n\n`
)
);
if (i++ >= 5) {
controller.enqueue(encoder.encode("</ol></body></html>"));
controller.close();
clearInterval(timer);
}
}, 1000);
}
});
return {
headers: {
"content-type": "text/html"
},
statusCode: 200,
body
};
});

For an extended example that demonstrates a more likely response streaming use case, consider this function:

const { stream } = require("@netlify/functions");
exports.handler = stream(async event => {
// Get the request from the request query string, or use a default
const pie =
event.queryStringParameters?.pie ??
"something inspired by a springtime garden";
// The response body returned from "fetch" is a "ReadableStream",
// so you can return it directly in your streaming response
const res = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
// Set this environment variable to your own key
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content:
"You are a baker. The user will ask you for a pie recipe. You will respond with the recipe. Use markdown to format your response"
},
// Use "slice" to limit the length of the input to 500 characters
{ role: "user", content: pie.slice(0, 500) }
],
// Use server-sent events to stream the response
stream: true
})
});
return {
headers: {
// This is the mimetype for server-sent events
"content-type": "text/event-stream"
},
statusCode: 200,
// Pipe the event stream from OpenAI to the client
body: res.body
};
});

When invoked this function sends a prompt to OpenAI and streams the response back to the client like a chatbot.

Keep the following limitations in mind when working with streaming functions:

  • 10 second execution limit. If the limit is reached, the response stops streaming.
  • 20 MB response size limit. Responses larger than 20 MB cannot be streamed.
  • Background Functions can’t stream responses.
  • On-demand Builders can’t stream responses.
  • Scheduled Functions can’t stream responses.

Background function format

This feature is in Beta and is available on Pro and Enterprise plans.

To create a background function, append the function name with -background. For example, netlify/functions/hello-background.js or netlify/functions/hello-background/index.js.

Background function syntax is similar to synchronous function syntax with a couple of key differences:

  • You will generally pass the function result to a destination other than the originating client.
  • Background functions don’t support response streaming because they don’t return responses.

Like the synchronous function format, each JavaScript file to be deployed as a background function must export a handler method. As with synchronous function invocation, Netlify provides the event and context parameters when a background function is invoked. Although background functions rely on asynchronous invocation, they don’t require the use of async JavaScript syntax.

Here’s a simplified example background function that you can use to test that your function runs longer than 30 seconds, count-background.js:

exports.handler = function(event, context) {
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
for (let i = 0; i < 60; i++) {
let date = new Date();
await sleep(1000);
console.log(date.toLocaleString(), i);
}
console.log("Done");
}
demo();
};
  • This function deploys to an endpoint at /.netlify/functions/count-background relative to the base URL of your site.
  • When invoked, the function returns an initial 202 success response.
  • When successfully executed, the function logs numbers 1 through 60.

For an extended example that demonstrates a more likely background function use case, consider this send-pdf-background.js function:

const { jsPDF } = require("jspdf");
const nodemailer = require("nodemailer");
const mg = require("nodemailer-mailgun-transport");
const transporter = nodemailer.createTransporter(
mg({
auth: {
api_key: process.env.MAILGUN_API_KEY,
domain: process.env.MAILGUN_DOMAIN
}
})
);
exports.handler = async function(event) {
const { content, destination } = JSON.parse(event.body);
console.log(`Sending PDF report to ${destination}`);
const report = Buffer.from(
new jsPDF().text(content, 10, 10).output("arraybuffer")
);
const info = await transporter.sendMail({
from: process.env.MAILGUN_SENDER,
to: destination,
subject: "Your report is ready!",
text: "Details in attached report PDF",
attachments: [
{
filename: `report-${new Date().toDateString()}.pdf`,
content: report,
contentType: "application/pdf"
}
]
});
console.log(`PDF report sent: ${info.messageId}`);
};
  • This background function deploys to an endpoint at /.netlify/functions/send-pdf-background relative to the base URL of your site.
  • When invoked, the function returns an initial 202 success response.
  • When successfully executed, a PDF report is generated and emailed as an attachment.

Environment variables

Netlify Functions have access to environment variables in the runtime environment. If you have the option to set specific scopes for your environment variables, the scope must include Functions to be available to functions during runtime.

You can also leverage build environment variables to configure how Netlify builds your functions. For example, you can use an environment variable to set the Node.js version.

Learn more about how to set and use environment variables with functions.

Manage dependencies

To optimize build performance, specify function dependencies in the top-level package.json file in the site’s base directory. Here’s an example of a recommended layout:

my-base-directory/
├─ package.json
├─ node_modules
└─ netlify/
└─ functions/
├─ hello.js
└─ send-pdf-background.js

With continuous deployment, Netlify automatically zips dependencies with your functions for deployment. To do this, Netlify’s build system installs your dependencies and parses each function file to note its dependencies. For each function, Netlify then pulls the required dependencies from the associated node_modules folder and zips them with the function file for deployment. For more details about how this bundling functionality works, visit the repository for the underlying module: @netlify/zip-it-and-ship-it.

Test locally

To streamline writing and testing your functions on Netlify, run a local development environment with Netlify Dev. This feature of Netlify CLI includes tools for local function development through a simulated Netlify production environment. The netlify dev command starts a framework server if a framework is detected and handles redirects, proxy rules, environment variables, and Netlify Functions.

To simulate Netlify Functions in a standalone server without the full overhead of Netlify Dev, serve functions locally with the netlify functions:serve CLI command (currently in beta). Then to debug functions, inspect the functions server process.

Next steps

Push your function source files to your Git provider for continuous deployment where Netlify’s build system automatically detects, builds, and deploys your functions. For more control over the process, learn about other workflows for deploying your functions including custom builds with continuous deployment and manual deploys with the Netlify CLI or API.

Monitor function logs and metrics in the Netlify UI to observe and help troubleshoot your deployed functions.

Netlify function logs are found in the Netlify UI. You can also stream Netlify function logs to the console with the Netlify CLI.

Create function file

To add a serverless function to your project, create a Go file in a dedicated function subdirectory in your functions directory following the instructions below for naming and coding your function. Netlify will access the functions directory during every build, preparing and deploying each supported code file as a function.

The default functions directory is YOUR_BASE_DIRECTORY/netlify/functions. You can optionally configure a custom functions directory.

Name your function

You must store your function in a subdirectory dedicated to the function. The function’s endpoint name is case-sensitive and determined by the name of its dedicated parent directory.

For example, to create a function with an endpoint name of hello, save the function file in one of the following ways:

  • netlify/functions/hello/hello.go
  • netlify/functions/hello/main.go

These formats would deploy a synchronous function that can be called on the following endpoint: /.netlify/functions/hello. The endpoint is relative to the base URL of your site. Here are some example full endpoint URLs: yoursitename.netlify.app/.netlify/functions/hello for a site using the default Netlify subdomain or www.yourcustomdomain.com/.netlify/functions/hello for a site using a custom domain.

To create a background function, append the function name with -background. For example, to create a background function with an endpoint name of hello-background, save the function file in one of these ways:

  • netlify/functions/hello-background/hello-background.go
  • netlify/functions/hello-background/main.go

These formats would deploy a background function that can be called on the following endpoint: /.netlify/functions/hello-background. The endpoint is relative to the base URL of your site. Here are some example full endpoint URLs: yoursitename.netlify.app/.netlify/functions/hello-background for a site using the default Netlify subdomain or www.yourcustomdomain.com/.netlify/functions/hello-background for a site using a custom domain.

Code your function

This section will help you learn how to write functions. It covers the syntax for both synchronous and background functions.

Synchronous function format

To create a synchronous function, use the following general syntax in your Go function file. This makes a handler function to receive invocation events:

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) {
// Your server-side functionality
}
func main() {
// Make the handler available for Remote Procedure Call
lambda.Start(handler)
}

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() {
lambda.Start(handler)
}
  • This function deploys to an endpoint at /.netlify/functions/hello relative to the base URL of your site.
  • A successful invocation returns the 200 status code and the string, “Hello, World”.

Synchronous functions can return a response object that includes the following information:

return &events.APIGatewayProxyResponse{
StatusCode: 200,
Headers: map[string]string{"Content-Type": "text/plain"},
MultiValueHeaders: http.Header{"Set-Cookie": {"Ding", "Ping"}},
Body: "Hello, World",
IsBase64Encoded: false,
}, nil

For more examples to help you learn how to create functions with Go, visit the AWS Lambda for Go repository.

Netlify can provide extra request information about the context in which the function was called, including certain Identity user information, using a ClientContext parameter.

To access the ClientContext data, do the following:

  • Use a handler definition that includes a Go Context struct.
  • Transform this object into a LambdaContext.

Here is an example:

package main
import (
"context"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-lambda-go/lambdacontext"
)
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
}
func main() {
lambda.Start(handler)
}

Background function format

This feature is in Beta and is available on Pro and Enterprise plans.

To create a background function, append the function name with -background. For example, netlify/functions/hello-background/hello-background.go or netlify/functions/hello-background/main.go.

Background function syntax is similar to synchronous function syntax, but you will generally pass the function result to a destination other than the originating client. Like the synchronous function format, a Go file to be deployed as a background function must include a handler function to receive invocation events.

Here’s a simplified example background function that you can use to test that your function runs longer than 30 seconds, count-background.go:

package main
import (
"log"
"time"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func handler(request events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
for i := 0; i < 60; i++ {
log.Println(i)
time.Sleep(1 * time.Second)
}
return nil, nil
}
func main() {
lambda.Start(handler)
}
  • This function deploys to an endpoint at /.netlify/functions/count-background relative to the base URL of your site.
  • When invoked, the function returns an initial 202 success response.
  • When successfully executed, the function logs numbers 1 through 60.

You can explore an extended background function example that demonstrates a more likely use case.

  • This event-triggered background function is called on a new user email and password signup and uses the ctx parameter to access the ClientContext.
  • When the function is executed, it finds and downloads a user’s Gravatar profile image, resizes the image to three different sizes, and saves these images to the site’s repository.
  • For more details, visit the example’s repository README. Note that this extended example doesn’t follow the file name requirements described on this page. That is because rather than using Netlify’s default automatic build workflow, this example uses a custom build with continuous deployment to compile save.go to identity-signup-background.

Environment variables

Netlify Functions have access to environment variables in the runtime environment. If you have the option to set specific scopes for your environment variables, the scope must include Functions to be available to functions during runtime.

You can also leverage build environment variables to configure how Netlify builds your functions. For example, you can use an environment variable to set the Node.js version.

Learn more about how to set and use environment variables with functions.

Test locally

To streamline writing and testing your functions on Netlify, run a local development environment with Netlify Dev. This feature of Netlify CLI includes tools for local function development through a simulated Netlify production environment. The netlify dev command starts a framework server if a framework is detected and handles redirects, proxy rules, environment variables, and Netlify Functions.

To simulate Netlify Functions in a standalone server without the full overhead of Netlify Dev, serve functions locally with the netlify functions:serve CLI command.

Next steps

Push your function source files to your Git provider for continuous deployment where Netlify’s build system automatically detects, builds, and deploys your functions. For more control over the process, learn about other workflows for deploying your functions including custom builds with continuous deployment and manual deploys with the Netlify CLI or API.

Monitor function logs and metrics in the Netlify UI to observe and help troubleshoot your deployed functions.

Netlify function logs are found in the Netlify UI. You can also stream Netlify function logs to the console with the Netlify CLI.