How to Develop Functions

Functions are blocks of code that run on demand without the need to manage any infrastructure. Develop on your local machine, test your code from the command line (using doctl), then deploy to a production namespace or App Platform — no servers required.


The development workflow of DigitalOcean Functions is based on the command line, so first, install doctl, the official DigitalOcean Command-Line Interface (CLI).

To get started, create a function using the command line to initialize a sample project directory on your local machine and deploy it to the cloud. The recommendations in this article can help you during your workflow for creating and testing functions.

List Deployed Functions

Use doctl to list the functions you have deployed to the current namespace:

doctl serverless functions list

Here is example output:

 Datetime        Access   Kind      Version  Actions                                           
 ─────────────── ──────── ───────── ──────── ───────────────────────────────────────────────── 
 05/10 13:56:34  web      nodejs:14 0.0.1    sample/hello  

This example lists a single Node.js function deployed called sample/hello.

Invoke a Function

After your function is deployed, you can invoke it from the command line using doctl or curl. You can also invoke it from the DigitalOcean Control Panel in your browser. We recommend using doctl.

To invoke your function using doctl, use the serverless functions invoke subcommand, replacing sample/hello with the name of your function:

doctl serverless functions invoke sample/hello

The function returns the response body in a JSON object:

{
  "body": "Hello stranger!"
}

Adding the --full flag to doctl serverless functions invoke returns a full activation record, which includes more information about the invocation such as the duration of execution, runtime, response status, and logs. Learn more in the activation records reference.

Invoke a Function with Parameters

To set parameters when invoking a function, use the -p or --param flag and give it a key:value pair.

doctl serverless functions invoke sample/hello --param name:sammy
{
  "body": "Hello sammy!"
}

You can use multiple -p or --param flags to pass more than one key:value pair:

doctl serverless functions invoke sample/hello -p name:sammy -p age:10

You can also format multiple parameters as a single, comma-separated list:

doctl serverless functions invoke sample/hello -p name:sammy,age:10

You can also pass in parameters from a JSON file using the -P or --param-file flags.

The curl command is a common tool for making web requests. All the functions you deploy have a public URL where you can invoke them with curl.

Use the functions get subcommand to find the URL of your function, replacing sample/hello with the name of your function:

doctl serverless functions get sample/hello --url

This command returns a URL similar to the following:

https://faas-nyc1-78edc.doserverless.co/api/v1/web/fn-EXAMPLE-706a-4f13-9c81-f24a3330260b/sample/hello

Use the bare curl command with your URL to fetch a response:

curl https://faas-nyc1-78edc.doserverless.co/api/v1/web/fn-EXAMPLE-706a-4f13-9c81-f24a3330260b/sample/hello

This returns the response body:

Hello stranger!

Invoke a Function with Parameters

You can add parameters to a curl request using the -d flag:

curl https://faas-nyc1-78edc.doserverless.co/api/v1/web/fn-feb132ee-706a-4f13-9c81-f24a3330260b/sample/hello \
  -d 'name=sammy'

You can send multiple parameters using multiple -d flags.

You can also send parameters as JSON using the same flag, but you must also send the appropriate Content-Type header:

curl https://faas-nyc1-78edc.doserverless.co/api/v1/web/fn-feb132ee-706a-4f13-9c81-f24a3330260b/sample/hello \
  -d '{"name":"sammy"}' \
  -H 'Content-Type: application/json'

The Functions control panel interface has a basic text editor for single-file functions and the ability to run functions, pass in parameters, and view output and logs.

To invoke a function in the control panel, click Functions in the left menu, then click on a namespace to go to its Overview page.

The overview tab of the a namespace with two example functions listed.

Then, click the name of the function you want to invoke to go to its Source tab.

The Source tab of a sample/hello function and the Output and Logs areas.

To invoke the function, press the green Run button. The function runs and prints output and logs:

The Source tab Output and Logs interface showing 'Hello stranger' output and a timestamped log line

The output of the function matches the content type. For example, if your function returns an image, the output section displays the image.

Invoke a Function with Parameters

To send parameters to your function, click the Parameters button next to the green Run button to open the Change Function Input window.

The function parameter input dialog textbox with JSON text defining name equals sammy.

Enter parameters as JSON-formatted text. If your JSON has formatting errors, the lines with issues have red highlights in right-hand margin and the problematic characters are be underlined with red squiggles.

Once your input has no formatting errors, click Save to save the new input.

Click Run again to see the output and logs for your function given the new input parameters.

Automatically Re-deploy Functions while Developing

While developing functions, having a development server watching for code changes can help automate build steps and speed up iteration. To watch a functions project directory and automatically re-deploy changes, use the serverless watch subcommand, replacing example-project with the path to the root of your project directory.

doctl serverless watch example-project

The command prints Watching and waits to detect changes in the directory.

Watching 'example-project' [use Control-C to terminate]

When you edit and save your function’s code, the watch command automatically redeploys your changes with an explanation:

Deploying 'example-project' due to change in 'packages/sample/hello.js'

To stop the watch command, enter CTRL+C in the terminal.

Inspect Logs

For asynchronous (or non-blocking) invocations only, any text your function sends to STDOUT is logged as part of an activation record. Function invocations through the authenticated REST API are non-blocking by default.

You can inspect logs from the command line with doctl or in the control panel. Each activation record also contains additional structured information about the function’s activation. See the activation records reference for more information.

To retrieve logs from the most recent function activation, use the serverless activations logs subcommand. The default --limit is 1, but this example uses --limit 3 to show the last three activations:

doctl serverless activations logs --limit 3

This returns a header with the activation ID, status, date and time, and function version information, followed by the actual logged output:

=== 49aa4a2bd3834635aa4a2bd383f63514 (success) 05/12 15:55:21 hello:0.0.3
2022-05-12T19:55:21.532898871Z stdout: Hello sammy
=== 918883de63b7403f8883de63b7a03f14 (success) 05/12 15:55:37 hello:0.0.3
2022-05-12T19:55:37.646627522Z stdout: Hello sammy
=== d4e9d0de96c3461aa9d0de96c3e61aa1 (success) 05/13 11:03:06 hello:0.0.5
2022-05-13T15:03:06.910748257Z stdout: Hello sammy

Add the --follow flag to follow the logs as they are generated (like tail -f). You can also filter down to a specific function or package by using the --function or --package flags.

This example tails logs for the sample/hello function:

doctl serverless activations logs --follow --function sample/hello

enter CTRL+C to stop continuously following the logs and return to your command prompt.

Retrieve Full Activation Records

Using the activation ID from the log output, you can retrieve the full activation record for more information:

doctl serverless activations get EXAMPLEdaf34232747f4c7ab34232747f

This returns the full JSON object for an activation, which includes logs, response status, response body, and other details that may be useful for debugging. Learn more in the activation records reference.

You can inspect function activation records and logs in the Logs tab of the current namespace:

The Logs tab of a Functions namespace showing dropdown selectors for 'Select Function' and 'Select Period', as well as a table of function activation logs.

Use the Select Function dropdown to filter the records by a package name or a single function name. Use the Select Period dropdown to filter the records by time period.

To view more details about an activation, including logged STDOUT text, click the + disclosure button on the left side of the record:

A detail view of a single activation record in the Logs tab, showing a portion of the JSON structure of an activation record.

This displays the complete JSON activation record. The logged STDOUT text is available under logs in the top level of the object. Learn more in the activation records reference.

Deploy to Production

The functions deployed to your Functions namespaces are production-ready, though we recommend that you additionally implement common DevOps patterns of versioning, continuous deployment, and rollback.

For a more managed production deployment, you can create a GitHub repository and deploy your functions as an App Platform component.

Use App Platform to deploy your Functions as a component of a production app.