Web functions let your custom runtime act as an HTTP server. Function Compute converts each invocation request into an HTTP request, forwards it to your server, and converts the server's HTTP response back into a function invocation response for the client.
Invocation methods
Function Compute supports two invocation methods:
| Method | Mode | When to use |
|---|---|---|
| HTTP calls (recommended) | Passthrough — Function Compute forwards the HTTP request directly to your server and returns the server's response to the client | Direct HTTP access via an HTTP trigger or a custom domain name |
| API calls | Conversion — Function Compute converts the InvokeFunction API request into an HTTP request before forwarding it | SDK-based invocations or event source integrations |
How it works
Each invocation follows this sequence:
Receive a request — Function Compute receives an invocation from a client via an HTTP trigger, a custom domain name, or the InvokeFunction API.
Convert to HTTP — The request is converted into an HTTP request and forwarded to your HTTP server.
Process the request — Your server handles the request and returns an HTTP response.
Report execution status — Optionally set the
x-fc-statusresponse header to indicate whether the function succeeded or failed.Return the response — Function Compute converts the HTTP response and returns it to the client.
Limitations
HTTP trigger
Each function version or alias supports only one HTTP trigger. For details, see Manage versions and Manage aliases.
Request limits
Requests that exceed the following limits return a 400 InvalidArgument error. Split oversized payloads or reduce header size before retrying.
| Limit | Max size |
|---|---|
| Header size (all keys and values combined) | 8 KB |
| Path size (including all query parameters) | 4 KB |
| Request body — synchronous invocation | 32 MB |
| Request body — asynchronous invocation | 128 KB |
Request headers cannot contain custom fields that start with x-fc- or the following reserved fields: connection, keep-alive.
Response limits
Responses that exceed the following limits return a 502 BadResponse error. Keep response headers concise to avoid this.
| Limit | Max size |
|---|---|
| Header size (all keys and values combined) | 8 KB |
Response headers cannot contain custom fields that start with x-fc- or the following reserved fields: connection, content-length, date, keep-alive, server, content-disposition:attachment.
When using the defaultaliyuncs.comdomain, Function Compute automatically adds thecontent-disposition: attachmentheader, which causes browsers to download the response as a file instead of rendering it. To remove this behavior, configure a custom domain name.
Custom domain name path mapping
Bind a custom domain name to map different HTTP access paths to your function. For details, see Configure a custom domain name.
HTTP calls (recommended)
In passthrough mode, Function Compute forwards the client's HTTP request directly to your HTTP server and returns the server's response to the client. System-reserved fields are filtered out — see Request limits and Response limits.
Request headers
Include the following headers in your request to control invocation behavior.
| Header | Type | Required | Valid values | Description |
|---|---|---|---|---|
X-Fc-Invocation-Type | String | No | Sync / Async | Invocation type. For details, see Invocation methods. |
X-Fc-Log-Type | String | No | Tail / None | Controls whether execution logs are returned. Tail returns the last 4 KB of logs. None (default) returns no logs. |
Response headers
Function Compute adds the following headers to each response.
| Header | Description | Example |
|---|---|---|
X-Fc-Request-Id | Unique ID for the function invocation | dab25e58-9356-4e3f-97d6-f044c4**** |
API calls
When you invoke a function using the InvokeFunction API (via an SDK or event source), Function Compute converts the API request into an HTTP request before forwarding it to your server.
InvokeFunction request conversion
| InvokeFunction field | Converted HTTP request |
|---|---|
event parameter | Request body |
path | /invoke |
method | POST |
Content-Type | application/octet-stream |
Example — request conversion:
| InvokeFunction request | HTTP request received by your server |
|---|---|
"hello world" | POST /invoke HTTP/1.1<br>Host: 21.0.X.X<br>Content-Length: 11<br><br>hello world |
InvokeFunction response conversion
Function Compute converts the HTTP response from your server back into an InvokeFunction response:
The HTTP response body becomes the InvokeFunction response body.
HTTP response headers and status code are discarded.
Example — response conversion:
| HTTP response from your server | InvokeFunction response |
|---|---|
HTTP/1.1 200 OK<br>Content-Type: application/octet-stream<br>Content-Length: 11<br><br>hello world | hello world |
HTTP/1.1 400 Bad Request<br>Content-Type: application/octet-stream<br>Content-Length: 28<br><br>{"errorMessage":"exception"} | {"errorMessage":"exception"} |
Report function execution status
Your HTTP server can report execution status to Function Compute using the x-fc-status response header. In the returned HTTP response, set both StatusCode and x-fc-status.
x-fc-status value | Meaning |
|---|---|
200 | Function executed successfully |
404 | Function execution failed |
If `x-fc-status` is not set: Function Compute assumes the invocation succeeded. If an exception occurs but is not reported, Function Compute still considers the execution successful. This may not affect the business logic, but it impacts monitoring and observability.

If `x-fc-status` is set: When an exception occurs, Function Compute records the failure and prints the stack trace to the function logs.

Code example
The following Python example implements a minimal HTTP server using the Flask framework. Create a Web Function and select Python 3.10 as the runtime before running this code.
import os
from flask import Flask, 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):
# Get the request ID injected by Function Compute
rid = request.headers.get(REQUEST_ID_HEADER)
# Read the raw request body
data = request.stream.read()
print("Path: " + path)
print("Data: " + str(data))
# Return a response body, status code, and a custom header
return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)Key points:
@app.route('/', defaults={'path': ''})— handles requests to the root path.@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])— handles dynamic paths for all supported HTTP methods; the path value is passed as thepathargument.request.headers.get(REQUEST_ID_HEADER)— reads thex-fc-request-idheader injected by Function Compute.request.stream.read()— reads the raw request body.return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]— returns a200response with aFunction-Nameheader sourced from theFC_FUNCTION_NAMEenvironment variable.