All Products
Search
Document Center

Function Compute:Web functions

Last Updated:Feb 02, 2024

This topic describes the methods, limits, and sample code of function invocations in a custom runtime.

Background

In custom runtimes, HTTP servers can be hosted. Function invocations can be converted into HTTP requests and sent to HTTP servers. Responses of HTTP servers can be sent to clients as responses of function invocations. The following figure shows the process.

image

Functions can be invoked by using one of the following methods:

  • HTTP calls (recommend): Functions can be invoked by using HTTP calls. For example, you can invoke a function by using an HTTP trigger or a custom domain name.

  • API calls: You can invoke a function by calling the InvokeFunction operation. For example, you can invoke a function by using an SDK or trigger a function by using an event source.

The formats of the requests and responses of HTTP servers vary based on the invocation method.

Limits

  • Only one HTTP trigger can be created for an HTTP function in each version or alias. For more information, see Manage versions and Manage aliases.

  • Limits on HTTP requests

    • Request headers do not support custom fields that start with x-fc- or the following fields:

      • connection

      • keep-alive

    • The system returns the 400 status code and InvalidArgument error code if a request exceeds one of the following limits:

      • Headers size: The total size of all keys and values in headers cannot exceed 8 KB.

      • Path size: The total size of the path, including all query parameters, cannot exceed 4 KB.

      • Body size: The total size of the body of a synchronous invocation request cannot exceed 32 MB. The total size of the body of an asynchronous invocation request cannot exceed 128 KB.

  • Limits on HTTP responses

    • Response headers do not support custom fields that start with x-fc- or the following fields:

      • connection

      • content-length

      • date

      • keep-alive

      • server

      • content-disposition:attachment

        Note

        For security reasons, if you use the default domain name aliyuncs.com of Function Compute, the server forcibly adds the content-disposition: attachment response header, which is used to download returned results from browsers as an attachment. To remove this limit, you must configure a custom domain name. For more information, see Configure a custom domain name.

    • If a response exceeds one of the following limits, the system returns status code 502 and error BadResponse:

      • Headers size: The total size of all keys and values in headers cannot exceed 8 KB.

  • Others

    You can map different HTTP paths for functions by binding a custom domain name. For more information, see Configure a custom domain name.

HTTP calls (recommend)

For HTTP calls, the Function Compute passes HTTP requests of clients to HTTP servers and responses of HTTP servers to clients by using the passthrough mode. Some system reserved fields cannot be passed. For more information, see Limits.

HTTP request headers

If you use an HTTP trigger or a custom domain name to invoke a function, you can use request headers to control behaviors of requests in Function Compute. The following table describes the details.

Parameter

Type

Required

Example

Description

X-Fc-Invocation-Type

String

No

Sync

The invocation method. For more information, see Invocation methods. Valid values:

  • Sync: synchronous invocations

  • Async: asynchronous invocations

X-Fc-Log-Type

String

No

Tail

The method used to return logs. Valid values:

  • Tail: returns the last 4 KB of logs that are generated for the current request.

  • None: does not return logs for the current request. This is the default value.

HTTP response headers

When you use an HTTP trigger or a custom domain name to invoke a function, the response contains some response headers that are automatically added by Function Compute. The following table describes the details.

Parameter

Description

Example

X-Fc-Request-Id

The request ID of the function invocation.

dab25e58-9356-4e3f-97d6-f044c4****

API calls

For function invocations that are initiated by the InvokeFunction operation, Function Compute converts requests sent from the InvokeFunction operation into HTTP requests and passes the requests to clients. The following conversion rules apply:

  • The event parameter of InvokeFunction is converted into the message body of an HTTP request.

  • path is set to /invoke.

  • method is set to POST.

  • Content-Type is set to application/octe-stream.

Function Compute converts responses of HTTP servers into responses of InvokeFunction and returns the responses to clients. The following conversion rules apply:

  • The HTTP response body is converted into the response body of InvokeFunction.

  • HTTP response headers and status code information are lost during the conversion.

Example of converting an InvokeFunction request

InvokeFunction request

HTTP request received by an HTTP server

InvokeFunction request content:

"hello world"
> POST /invoke HTTP/1.1
> Host: 21.0.0.3
> Content-Length: 11
> Content-Type: application/octet-stream

hello world

Sample output of the InvokeFunction response

HTTP Response

Response of InvokeFunction

< HTTP/1.1 200 OK
< Date: Mon, 10 Jul 2023 07:02:15 GMT
< Content-Type: application/json
< Content-Length: 11
< Connection: keep-alive

hello world

hello world
< HTTP/1.1 400 Bad Request
< Date: Mon, 10 Jul 2023 07:02:15 GMT
< Content-Type: application/json
< Content-Length: 28
< Connection: keep-alive

{"errorMessage":"exception"}
{"errorMessage":"exception"}

Sample code

You can implement HTTP servers in any language. Python is used as an example in this topic.

Note

The sample code depends on the Python environment and the Flask library. We recommend that you select Web Function as the method to create the function and use Python 3.10 as the runtime.

import os
from flask import Flask
from flask import request

REQUEST_ID_HEADER = 'x-fc-request-id'
app = Flask(__name__)


@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def hello_world(path):
    rid = request.headers.get(REQUEST_ID_HEADER)
    data = request.stream.read()
    print("Path: " + path)
    print("Data: " + str(data))
    return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9000)

    

Description:

  • @app.route('/', defaults={'path': ''}): the default route, which corresponds to the root directory.

  • @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE']): a dynamic route that contains the path parameter. GET, POST, PUT, and DELETE requests can be processed. The value of the path parameter is passed to the hello_world function as the path parameter.

  • rid = request.headers.get(REQUEST_ID_HEADER): obtains the value of the x-fc-request-id field in the request header.

  • data = request.stream.read(): reads the content of the request and assigns it to the data variable.

  • return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]: returns a response body that contains "Hello, World! "and sets the status code to 200 and a tuple that contains the Function-Name header.