StediDOCS
This product is in Public Preview

Tutorial

Updated July 5, 2022

In this tutorial, we will show you how to deploy your first Stedi Function using our API. You can find more detailed information in the API docs.

Authentication

Before you can get started with the API, you need an API key. If you already have an API key for another Stedi product, you can use that here as well; you don’t need a separate key for Functions.

Once you have the key, include it in every call to the API as part of the Authorization header of the HTTP request.

Authorization: Key your-api-key

If you’d like more information about authentication, take a look at our Authentication guide.

Basics

Code template

Your code must include a function called handler that looks like the following.

exports.handler = async function (event, context) {
  return {};
};

An event is a JSON-formatted document that you pass in when you invoke the function; it contains data for a function to process. context contains information about the execution environment that the function is running in.

When writing a function, you should always return a value, or you’ll receive an error. Other than that, the return value is up to you.

Create a Function using the UI

In the web UI, you can create a function by clicking Create function, adding code to the editor, and clicking Save.

Create a Function using the API

You can also create functions via the API. The following example creates a new function called example-function and includes the JavaScript code as a string.

POST https://functions.cloud.us.stedi.com/2021-11-16/functions HTTP/1.1
Content-Type: application/json
Authorization: Key your-api-key

{
  "functionName": "example-function",
  "code": "exports.handler = async function (event, context) {\n  console.log('This is exciting!');\n  return { greeting: 'Hello, world!' }\n};"
}

A major downside of both the UI and the API methods shown above is that you can’t include multiple files, such as external packages. You can remedy this by creating a deployment package—which is a zip file with multiple files that include your code and libraries—and passing that via API instead.

Providing code as a zipped package via API

With this method, you include the zip file as a base64-encoded string in the API request. There are a few steps involved to create the zip file for every deployment;

  • Run 'npm build' to download all required node modules.
  • Create a zip file with your code and modules.
  • Convert the zip file to a base64-encoded string.
  • Include the base64-encoded string in a request to the Functions API.

We encourage to do this through our deployment script linked on the Stedi starter kit on GitHub. In the web-request tutorial, you can find the instructions how to use the build script to create or update functions.

Invoke a Function using the UI

In the Functions UI, you can invoke your function by clicking Execute. Do remember to save your function before executing it. If you uploaded a package using the API, the UI won’t show the code of your function. You can still invoke it, though.

When the function is done, you can view the invocation result, which includes the function return value and the logs.

Screenshot of Stedi Terminal homepage

Invoke a Function using the API

You invoke a function with the following API call.

POST https://functions.cloud.us.stedi.com/2021-11-16/functions/example-function/invocations HTTP/1.1
Content-Type: application/json
Accept: application/octet-stream
Authorization: Key your-api-key

The response will contain the return value of the function.

{"greeting":"Hello, world!"}

Passing data into a function

When you invoke a function, you can pass data into it. This data is available in the function through the event object.

The following function expects you to pass in a name and will echo that name to the log, with a little embellishment.

exports.handler = async function (event, context) {
  console.log(`Well hello, my dear ${event.name}.`);
  return {};
};

Passing data in the UI

If you click on Edit invocation payload, you can type in the input you want to pass to the function.

The invocation payload will be saved in your browser’s local storage, so you won’t have to type it in each time.

Screenshot of Stedi Terminal homepage

Passing data through the API

Passing data into a function using the API is as simple as putting it in the request body.

POST https://functions.cloud.us.stedi.com/2021-11-16/functions/example-function/invocations HTTP/1.1
Content-Type: application/json
Authorization: Key your-api-key

{
  "name": "Mrs. Longprattle"
}

Updating a function

Updating a function is similar to creating a function: you can specify code as a string in the code field or as a zipped package in the package field. The differences are that you specify the function name in the URL instead of the body and that you use PUT instead of POST.

PUT https://functions.cloud.us.stedi.com/2021-11-16/functions/example-function/ HTTP/1.1
Content-Type: application/json
Authorization: Key your-api-key

{
  "code": "exports.handler = async function (event, context) {\n  console.log('This is familiar.');\n  return { greeting: 'Hello again.' }\n};"
}

Making it useful

Using third-party libraries

You can use any third-party library you want by zipping it along with your own code. This does require you deploy your function using the API, because the Functions UI doesn’t yet support zipped packages.

A JavaScript example

For example, the following code translates Markdown to HTML, but it requires the Marked library to do so.

import { marked } from "marked";

exports.handler = async function (event, context) {
  return { html: marked.parse(event.markdown) };
};

You can install the Marked library locally by running npm.

npm install marked

You then create a package by zipping the node_modules directory along with your function code.

zip package -r index.js node_modules/

After you’ve base64-encoded the zipped package, you can use it to create a new function or update an existing one. For example, the following curl command updates example-function. Just make sure you set the environment variable STEDI_API_KEY to your API key.

curl --request PUT https://functions.cloud.us.stedi.com/2021-11-16/functions/example-functions \
  --header "Content-Type: application/json" \
  --header "Authorization: Key ${STEDI_API_KEY}" \
  --data-raw "{
    \"package\": \"$(base64 -i package.zip)\"
  }"

When calling this function, you need to pass in some Markdown, which doesn’t look pretty when you’re using curl, but that doesn’t mean it’s hard.

curl --request POST https://functions.cloud.us.stedi.com/2021-11-16/functions/example-function/invocations \
  --header "Authorization: Key ${STEDI_API_KEY}" \
  --header "Accept: application/octet-stream" \
  --data-raw "{ \"markdown\": \"# Greetings\nHello, world\" }"

Calling web APIs

A function has access to the wider Internet, meaning you can call any public web API. The following example calls Stedi’s Converter API because we like to promote our own products, but the principle is the same for any web API.

const axios = require("axios");

exports.handler = async function (event, context) {
  let response = await axios.post(
    "/2021-10-01/csv_to_json",
    {
      input: `
      title,artist,duration
      Every Little Older Spell,Hubber,191
      Snobs Are Sexy,Down The Drain,147
      The Unguessable,Foon,213
    `,
    },
    {
      headers: {
        Authorization: `Key ${event.apiKey}`,
        "Content-Type": "application/json",
      },
    },
  );
  return response.data;
};

This code uses the Axios library, so it needs to be included in the package. The Converter API needs an API key and this function expects you to pass it in using the event object.

POST https://functions.cloud.us.stedi.com/2021-11-16/functions/example-function/invocations HTTP/1.1

Content-Type: application/json
Authorization: Key your-api-key
Accept: application/octet-stream

{
  "apiKey": "your-api-key"
}