Skip to content

GoogleCloudPlatform/functions-framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 

Repository files navigation

Functions Framework

The Google Cloud Function Frameworks are open source libraries for writing portable Google Cloud functions -- brought to you by the Google Cloud Functions team.

The Functions Framework lets you write lightweight functions that run in many different environments, including:

These functions allow you to easily handle HTTP requests or CloudEvents in a Functions as a Service (FaaS) programming style.

Video

Watch a video about the Functions Framework

Languages & Test Status

The Functions Framework is implemented for these runtimes:

Languages Unit Tests Lint Test Conformance Tests
Node.js
Go
Java
PHP
Python
Ruby
.NET
C++
Dart

Community Function Frameworks

Legend:

  • Unit: Tests basic functionality of framework.
  • Lint: Tests code style.
  • Conformance: Tests adherence to the Functions Framework contract.

Specification Summary

A Functions Framework instantiates web server and invokes function code in response to an HTTP (http) or CloudEvent (cloudevent) request depending on the function's signature type. A Functions Framework may also optionally support functions with signature type event for legacy-style events.

The Functions Framework library may be configurable via command-line flags, environment variables, or within the function code itself:

Required Command-line flag Environment variable Description
YES --port PORT The port on which the Functions Framework listens for requests. Default: 8080
YES --target FUNCTION_TARGET The name of the exported function to be invoked in response to requests. Default: function
NO --signature-type FUNCTION_SIGNATURE_TYPE The signature used when writing your function. Controls unmarshalling rules and determines which arguments are used to invoke your function. The Functions Framework library may provide a way to express the function signature type in code, such as through registration APIs or annotations, instead of by flag or environment variable. Default: http; accepted values: http or cloudevent

Note: SIGNATURE_TYPE: event supports legacy, non-CloudEvent events. Support for these event formats are not required for Function Frameworks.


Functions Framework Contract

Note: This section is useful for Function Framework builders. Developers should view individual function framework repos for how to use a specific framework.

Test framework conformance with this tool: https://github.com/GoogleCloudPlatform/functions-framework-conformance

This contract builds upon the baseline compliance of the existing Cloud Run contract (e.g. the Knative Runtime Contract), which itself is built on OCI.

Goal

Functions Frameworks aim to minimize the amount of boilerplate and configuration required to create a runnable stateless container. The overall goal is to maximize productivity and free the developer from repetitive development tasks that do not directly contribute to solving customer problems.

Components

A Functions Framework consists of two parts:

  • A package that instantiates a web server and invokes function code in response to an HTTP request. This package may include additional functionality to further minimize boilerplate.
  • A script or tool that converts a source code transform of function code into app code ("the function-to-app converter")

Runtime and Lifecycle

Statefulness

Functions are generally deployed to stateless compute environments. In such an environment, the container or other environment that is running the function may be instantiated from scratch, paused, started or stopped based on inbound request volume.

The framework should be able to gracefully handle these dynamics, for example, by minimizing container and framework startup times. The framework should be long-lived and able to handle repeated invocations of the developer's function.

Lifecycle

The framework must load the function located and defined by the FUNCTION_TARGET environment variable on startup and create a local web server that listens for inbound HTTP requests. As stated in the Knative serving contract (Process), the web server must listen for ingress requests on the port defined by the PORT environment variable.

When a caller sends an HTTP request to the web server, the framework must take unmarshalling steps according to the developer's specified function signature type. The function must then be invoked by passing appropriate arguments conforming to the developer's specified function signature type.

When the function signals that it has completed executing (i.e., "completion signalling"), the framework must respond to the caller. Depending on the developer's function signature type, the framework may first need to marshall objects returned by the developer's function into an HTTP response.

No work is done after a response is sent.

For performance, efficiency and correctness reasons, the framework must be able to handle multiple concurrent invocations of the developer's function.

When the framework and function are deployed as a container to a Knative environment, additional Lifecycle considerations apply. As a general rule of thumb, frameworks should do as much as possible to ensure they are ready to receive traffic before listening on the HTTP port.

URL Space

Note: URL definitions are found in RFC 3986.

The framework's web server must listen to ingress HTTP requests defined with the following URL scheme using the PORT specified above:

https://hostname:$PORT

For example, the hostname of a process running the functions framework running the function my-function at localhost on 8080 would result in the URL:

https://localhost:8080

Requesting this URL would invoke the function $FUNCTION_TARGET.

In a different example, a service using the Functions Framework could have the url us-central1-my-gcp-project.cloudfunctions.net/my-function.

Note that the framework must listen to all inbound paths (.*) and route these requests to the function, with the following exceptions:

  • /robots.txt - must respond with 404 without invoking function
  • /favicon.ico - must response with 404 without invoking function

Supported Function Types

The framework must support at least the http and cloudevent function types. The framework may support legacy-style event function types. In statically typed languages, the framework must include an additional function type whereby the user can define unmarshalling rules. These function types dictate:

  • The steps taken by the framework in response to ingress requests
  • The function signatures which developers must adhere to when writing functions for use with a Functions Framework
  • The mechanism by which the developer signals that the function has completed performing useful work

The developer must signal the function's signature type to the framework. This enables the framework to take appropriate unmarshalling, invocation and completion signalling steps.

HTTP Functions (Signature Type: http)

The Functions Framework must support signature type http.

When the container receives an ingress request, the framework must invoke the developer's function by passing a language-idiomatic representation of HTTP objects as arguments to the function. These objects must enable the developer to perform common HTTP tasks, such as inspecting the request's content encoding or headers. These objects should be accurate representations of the HTTP request received by the execution environment (i.e., path, body and headers should not be modified before passing them to the user's function).

CloudEvents Functions (Signature Type: cloudevent)

The Functions Framework must support signature type cloudevent.

When the container receives an ingress request, the framework must invoke the developer's function by passing an object corresponding to a CloudEvents type. This object does not expose HTTP semantics to the developer's function. The framework must handle unmarshalling HTTP requests into the CloudEvents object that is passed to the developer's function, and should support both binary and structured content modes for incoming HTTP CloudEvent requests. This is usually done through a CloudEvents SDK.

Your function have must use the following signature:

  • 1st parameter cloudevent

The developer's function must either explicitly or implicitly signal that it has completed performing useful work. The function may explicitly signal this condition by explicitly returning. The function may implicitly signal this condition by simply evaluating until it reaches the end of the function's code block.

Legacy Events (Signature Type: event)

The Functions Framework may support signature type events. This signature supports non-CloudEvent style events. Your function have must use the following signature:

  • 1st parameter data
  • 2nd parameter context

Where the parameters have the contents detailed in background functions.

HTTP Headers

Traceparent Header

In addition to the standard CloudEvent properties, the framework may add a traceparent property to the cloudevent object, following the Distributed Tracing extension. This value for this property is retrieved from the HTTP header name: traceparent.

More about the traceparent header can be read in W3C Trace Content docs.

No eTag Header

To prevent caching, by default, the Functions Framework should not send an etag header in the HTTP response.

Configuration

The framework must allow the developer to specify (1) the port ($PORT) on which the web server listens, (2) the target function to invoke in response to ingress requests and (3) the function's signature type.

This configuration may be provided implicitly or explicitly. In some languages, the function's signature type can be inferred by via reflection, inspecting the developer's function signatures, annotations, and exports - using language-idiomatic methods that feel natural to developers. In some languages, the signature type may need to be explicitly signalled by the developer.

The framework may, for developer convenience, provide multiple mechanisms (for example, environment variables, command-line arguments, configuration files) for developers to specify configuration. If multiple methods are provided, the order of precedence must be the following:

  1. Source code configurations
  2. Command-line flags
  3. Environment variables

Observability

The framework may provide built-in observability support. For example, the framework might automatically add Trace spans, collect profiling information or provide a logger.

If such integrations are provided, they must be clearly documented and users must be able to enable or disable them. Disabling these integrations should result in a graceful default experience.

Function-to-app Converter

A function-to-app converter must be provided. This converter takes function code as input and creates app code as output. This app code must be buildable into a container using an app-to-container converter (such as a Cloud Native Buildpack).

A developer may opt to perform these steps manually rather than using the function-to-app converter. For this reason, it is important that the steps taken by the function-to-app converter are idiomatic to the programming language selected for the Functions Framework. For example, a function-to-app converter written for a Python Functions Framework should expose a WSGI app which can be used by multiple HTTP servers such as gunicorn. A Go function-to-app converter would add a dependency via a go.mod file and add a boilerplate main.go file.

Example steps taken by the function-to-app converter may include:

  • directory layout
  • injecting a dependency into a dependencies file
  • creating a boilerplate main package

Stdout/Stderr and Logging expectations

Application logs to stdout/stderr within application code and logs from the Functions Framework itself are expected to appear in stdout/stderr of the process running the Functions Framework.

HTTP Status Codes

The framework should return 4XX HTTP status error codes for client errors and 5XX HTTP status error codes for Function Framework errors according to RFC 7231. Examples:

  • 4xx: External errors from clients of the Functions Framework
    • 400: Bad Request (i.e. malformed CloudEvent)
    • 429: Too many requests to the framework
  • 5xx: Internal errors from the Functions Framework itself
    • 504: Function timeout

About

The Contract for Building New Function Frameworks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published