Call an API from a Lambda

FusionAuth Reactor logo

This feature is only available in an Essentials or Enterprise plan. Please visit our pricing page to learn more.

Overview#

Lambda HTTP Connect allows you to make HTTP requests from within a lambda with fetch(). Lambdas can contact any URL accessible from your FusionAuth instance.

This features allows you to access data from external systems to configure token claims or to add data to a user profile. It also allows you to push profile or other data from FusionAuth to an external system as needed.

Here's a video showing more details about Lambda HTTP Connect:

Play

Example Lambda#

To make a request, call fetch(), passing:

  • a string containing a URL
  • optionally, an object containing options to configure the request.

The following lambda makes an HTTP GET request to an API hosted at api.example.com with the Content-Type header set to application/json. The lambda uses the response returned from that API to add additional claims to a JWT:

A lambda which adds claims based on an external API.

function populate(jwt, user, registration) {
  var response = fetch("https://api.example.com/api/status?" + user.id, {
    method: "GET",
    headers: {
      "Content-Type": "application/json"
    }
  });

  if (response.status === 200) {
    // assuming successful response looks like:
    // {"status":"statusValue"}
    var jsonResponse = JSON.parse(response.body);
    jwt.status = jsonResponse.status;
  } else {
    jwt.status = "basic";
  }
}

You can also call FusionAuth APIs with a valid API key:

A lambda which adds claims based on a FusionAuth API.

function populate(jwt, user, registration) {
  var response = fetch("http://localhost:9012/api/group", {
    method: "GET",
    headers: {
      "Authorization": "bf69486b-4733-4470-a592-f1bfce7af580"
    }
  });

  if (response.status === 200) {
    // a successful response as defined in the Groups API
    var jsonResponse = JSON.parse(response.body);
    jwt.groups = jsonResponse.groups;
  } else {
    jwt.groups = [];
  }
}

Use the local FusionAuth HTTP port (fusionauth-app.http-local.port, default value 9012), whenever making a FusionAuth API call in a lambda. Doing so minimizes network traffic contention and improves performance.

Options#

Timeouts#

Available Since Version 1.55.1

Within lambda functions, external requests should always return quickly. Every moment of delay causes additional latency during the FusionAuth request, which can reduce the performance of FusionAuth or even cause errors. This happens because lambda functions are blocking, rather than asynchronous: FusionAuth must wait for the lambda to complete before the user interaction can complete.

Lambdas use default connect and read timeouts of 2 seconds. But you can modify these timeouts if you know a request may be slow. To specify a timeout, pass the optional second parameter to fetch() and assign a value and assign an integer value (in milliseconds) to the connectTimeout or readTimeout fields in that object:

var response = fetch("https://api.example.com/api/status", {
    method: "GET",
    connectTimeout: 42000,   // 42,000 ms, or 42 seconds
    readTimeout: 42000       // 42,000 ms, or 42 seconds
  });

Body#

By default, fetch() does not send a request body. To specify a request body, pass the optional second parameter to fetch() and assign a string value to the body field in that object:

var response = fetch("https://api.example.com/api/status", {
    method: "PUT",
    body: "test body pls ignore"
  });

Method#

By default, fetch() issues an HTTP GET request. To use a different method, pass the optional second parameter to fetch() and pass any valid HTTP method as a string to the method field in that object:

var response = fetch("https://api.example.com/api/status", {
    method: "DELETE"
  });

Headers#

By default, fetch() does not specify any headers. To specify headers in a request, pass the optional second parameter to fetch() and assign a value to the header field in that object:

var response = fetch("https://example.org", {
  method: "GET",
  headers: {
    "Content-Type": "application/json"
  }
});

You can provide request header values in the following ways:

  • An anonymous object:

    headers: {
       "Content-Type": "application/json"
    }
  • A hash or map:

    headers: new Headers({
       "Content-Type": "application/json"
    })
  • An array:

    headers: new Headers([
        ["Content-Type", "application/json"]
    ])

Response#

fetch() returns an object that contains the following fields:

headersObject

The headers returned by the response. The keys of this object are the header names. All header keys are lower cased.

statusInteger

The HTTP status code of the response.

bodyString

The body of the response.

Securing API Keys In Lambdas#

Available Since Version 1.64.0

To securely store secret values used in lambdas, like API keys and application passwords, use a lambda secret. To create a secret, open the Admin UI and navigate to Settings -> Key Master .

To access secrets, use the context parameter. Pass a secret name to context.services.secrets.get('<key>') to retrieve the corresponding secret value as a string:

function populate(jwt, user, registration, context) {
  var apiKey = context.services.secrets.get('my-api-key');
  if (apiKey) {
    jwt.apiKeyPresent = true;
  }
}

Lambda HTTP Connect Limitations#

Do not call any FusionAuth API that itself invokes the calling lambda: the circular dependency on your lambda will cause the request to fail. For example, in a JWT Populate lambda, do not invoke the Login API.

The fetch method in a lambda does not implement the entire fetch API as implemented in a browser: for example, the first argument to fetch must always be a string.