Skip to main content

Function

The cloud.Function resource represents a serverless function for performing short, stateless tasks. Functions are typically used to run business logic in response to events, such as a file being uploaded to a bucket, a message being pushed to a queue, or a timer expiring.

When a function is invoked on a cloud provider, it is typically executed in a container/host which is provisioned on demand.

Functions may be invoked more than once, and some cloud providers may automatically retry failed invocations. For performance reasons, most cloud providers impose a timeout on functions, after which the function is automatically terminated.

Usage

A function can be invoked in two ways:

  • invoke() - Executes the function with a payload and waits for the result.
  • invokeAsync() - Kicks off the execution of the function with a payload and returns immediately while the function is running.
bring cloud;
bring util;

// defining a cloud.Function resource
let countWords = new cloud.Function(inflight (payload: Json?): Json => {
return "{payload?.tryAsStr()?.split(" ")?.length ?? 0}";
}) as "countWords";

let longTask = new cloud.Function(inflight () => {
util.sleep(30s);
log("done!");
});

new cloud.Function(inflight () => {
let sentence = "I am a sentence with 7 words";
// invoking cloud.Function from inflight context
let wordsCount = countWords.invoke(sentence);
log("'{sentence}' has {wordsCount ?? "0"} words");

longTask.invokeAsync("");
log("task started");
}) as "Invoke Me";

Function container reuse

Most cloud providers will opportunistically reuse the function's container in additional invocations. It is possible to leverage this behavior to cache objects across function executions using inflight new and inflight fields.

The following example reads the bigdata.json file once and reuses it every time query() is called.

bring cloud;

let big = new cloud.Bucket();

big.addObject("bigdata.json", Json.stringify({
"my-key": "my-value"
}));

class MyDatabase {
inflight bigdata: Json;
inflight new() {
// download big data once
this.bigdata = big.getJson("bigdata.json");
}

pub inflight query(key: str): Json {
return this.bigdata.get(key);
}
}

let db = new MyDatabase();

new cloud.Function(inflight () => {
log(Json.stringify(db.query("my-key")));
});

Target-specific details

Simulator (sim)

The sim implementation of cloud.Function runs the inflight code as a JavaScript function.

By default, a maximum of 10 workers can be processing requests sent to a cloud.Function concurrently, but this number can be adjusted with the concurrency property:

bring cloud;

new cloud.Function(inflight () => {
// ... code that shouldn't run concurrently ...
}, concurrency: 1);

AWS (tf-aws and awscdk)

The AWS implementation of cloud.Function uses AWS Lambda.

Adding custom IAM permissions

To add extra IAM permissions to the function, you can use the aws.Function class as shown below.

bring aws;
bring cloud;

let f = new cloud.Function(inflight () => {
log("Hello world!");
});
if let lambdaFn = aws.Function.from(f) {
lambdaFn.addPolicyStatements(
aws.PolicyStatement {
actions: ["ses:sendEmail"],
effect: aws.Effect.ALLOW,
resources: ["*"],
},
);
}

Accessing the Lambda context

To access the AWS Lambda context object, you can use the aws.Function class as shown below.

bring aws;
bring cloud;

let f = new cloud.Function(inflight () => {
if let ctx = aws.Function.context() {
log(ctx.logGroupName); // prints the log group name
log(ctx.logStreamName); // prints the log stream name

let remainingTime = ctx.remainingTimeInMillis();
assert(remainingTime > 0);
}
});

The context() method returns nil when ran on non-AWS targets.

Adding Lambda layers

To add a Lambda layer to the function, you can use the aws.Function class as shown below.

bring aws;
bring cloud;

let f = new cloud.Function(inflight () => {
log("Hello world!");
});
if let lambdaFn = aws.Function.from(f) {
lambdaFn.addLambdaLayer("arn:aws:lambda:us-west-2:123456789012:layer:my-layer:1");
}

In some scenarios, you might want to a Lambda layer to be automatically added to all Lambda function's that use a class's inflight methods. You can achieve this by using the onLift or onLiftType hook.

bring aws;
bring cloud;

class Datadog {
pub inflight fetchMetrics() {
// ...implementation...
}
pub onLift(host: std.IInflightHost, ops: Array<str>) {
// Note: the "ops" argument is an array of inflight methods that were used
// so you could conditionally add the layer based on the methods called
if let lambdaFn = aws.Function.from(host) {
lambdaFn.addLambdaLayer("arn:aws:lambda:us-west-2:123456789012:layer:datadog-layer:1");
}
}
}

let d = new Datadog();

let api = new cloud.Api();
api.get("/metrics", inflight () => {
d.fetchMetrics();
});

In the previous example, a Lambda function is implicitly created for handling the "/metrics" endpoint, and the datadog-layer is automatically added to it.

Azure (tf-azure)

The Azure implementation of cloud.Function uses Azure Functions.

🚧 invoke API is not supported yet (tracking issue: #1371)

GCP (tf-gcp)

🚧 Not supported yet (tracking issue: #614)

API Reference

Function

A function.

Initializers

bring cloud;

new cloud.Function(handler: IFunctionHandler, props?: FunctionProps);
NameTypeDescription
handler
IFunctionHandler
No description.
props
FunctionProps
No description.

handlerRequired

propsOptional

Methods

Preflight Methods
NameDescription
addEnvironment
Add an environment variable to the function.
Inflight Methods
NameDescription
invoke
Invokes the function with a payload and waits for the result.
invokeAsync
Kicks off the execution of the function with a payload and returns immediately while the function is running.

addEnvironment
addEnvironment(name: str, value: str): void

Add an environment variable to the function.

nameRequired
  • Type: str

valueRequired
  • Type: str

invoke
inflight invoke(payload?: Json): Json?

Invokes the function with a payload and waits for the result.

payloadOptional

payload to pass to the function.

If not defined, an empty string will be passed.


invokeAsync
inflight invokeAsync(payload?: Json): void

Kicks off the execution of the function with a payload and returns immediately while the function is running.

payloadOptional

payload to pass to the function.

If not defined, an empty string will be passed.


Static Functions

NameDescription
onLiftType
A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.
toInflight
Generates an asynchronous JavaScript statement which can be used to create an inflight client for a resource.

onLiftType
bring cloud;

cloud.Function.onLiftType(host: IInflightHost, ops: MutArray<str>);

A hook called by the Wing compiler once for each inflight host that needs to use this type inflight.

The list of requested inflight methods needed by the inflight host are given by ops.

This method is commonly used for adding permissions, environment variables, or other capabilities to the inflight host.

hostRequired

opsRequired
  • Type: MutArray<str>

toInflight
bring cloud;

cloud.Function.toInflight(obj: IResource);

Generates an asynchronous JavaScript statement which can be used to create an inflight client for a resource.

NOTE: This statement must be executed within an async context.

objRequired

Properties

NameTypeDescription
node
constructs.NodeThe tree node.
env
MutMap<str>Returns the set of environment variables for this function.

nodeRequired
node: Node;
  • Type: constructs.Node

The tree node.


envRequired
env: MutMap<str>;
  • Type: MutMap<str>

Returns the set of environment variables for this function.


Structs

FunctionProps

Options for Function.

Initializer

bring cloud;

let FunctionProps = cloud.FunctionProps{ ... };

Properties

NameTypeDescription
concurrency
numThe maximum concurrent invocations that can run at one time.
env
MutMap<str>Environment variables to pass to the function.
logRetentionDays
numSpecifies the number of days that function logs will be kept.
memory
numThe amount of memory to allocate to the function, in MB.
timeout
duration
The maximum amount of time the function can run.

concurrencyOptional
concurrency: num;
  • Type: num
  • Default: platform specific limits (100 on the simulator)

The maximum concurrent invocations that can run at one time.


envOptional
env: MutMap<str>;
  • Type: MutMap<str>
  • Default: No environment variables.

Environment variables to pass to the function.


logRetentionDaysOptional
logRetentionDays: num;
  • Type: num
  • Default: 30

Specifies the number of days that function logs will be kept.

Setting negative value means logs will not expire.


memoryOptional
memory: num;
  • Type: num
  • Default: 1024

The amount of memory to allocate to the function, in MB.


timeoutOptional
timeout: duration;

The maximum amount of time the function can run.


Protocols

IFunctionHandler

Inflight client: @winglang/sdk.cloud.IFunctionHandlerClient

A resource with an inflight "handle" method that can be used to create a cloud.Function.

IFunctionHandlerClient

Inflight client for IFunctionHandler.

Methods

NameDescription
handle
Entrypoint function that will be called when the cloud function is invoked.

handle
inflight handle(event?: Json): Json?

Entrypoint function that will be called when the cloud function is invoked.

eventOptional