An HTTP trigger gives your function an HTTP(S) endpoint — called a function URL — so clients can invoke the function directly with an HTTP request. This topic covers how HTTP triggers work in built-in runtimes. For custom runtimes, see Web functions.
In Function Compute (FC) 3.0, HTTP trigger behavior for custom runtimes and Custom Container runtimes is identical to FC 2.0. Built-in runtimes behave differently, as described below.
Prerequisites
Before you begin, review the following topics on HTTP triggers:
How it works
When a client calls a function URL in a built-in runtime, Function Compute maps the HTTP request to an event object (event) and passes it to your function handler. After the function completes, Function Compute maps the return value to an HTTP response and sends it back to the client.
Request struct
Request struct format
{
"version": "v1",
"rawPath": "/example",
"body": "Hello FC!",
"isBase64Encoded": false,
"headers": {
"header1": "value1",
"header2": "value1,value2"
},
"queryParameters": {
"parameter1": "value1",
"parameter2": "value1,value2"
},
"requestContext": {
"accountId": "123456*********",
"domainName": "<http-trigger-id>.<region-id>.fcapp.run",
"domainPrefix": "<http-trigger-id>",
"http": {
"method": "GET",
"path": "/example",
"protocol": "HTTP/1.1",
"sourceIp": "11.11.11.**",
"userAgent": "PostmanRuntime/7.32.3"
},
"requestId": "1-64f6cd87-*************",
"time": "2023-09-05T06:41:11Z",
"timeEpoch": "1693896071895"
}
}The following table describes the fields:
| Field | Description | Example |
|---|---|---|
version | Payload format version. Currently v1. | v1 |
rawPath | URL-encoded request path. For a request to https://{url-id}.{region}.fcapp.run/example, the value is /example. For the decoded path, use requestContext.http.path. | /example |
body | Request body. Function Compute Base64-encodes binary data during mapping. | Hello FC! |
isBase64Encoded | Whether the request body is Base64-encoded. Valid values: true, false. | false |
headers | Request headers as key-value pairs. Multiple values for the same key are comma-separated. Function Compute 3.0 converts the first letter of each header key to uppercase (normalization). For details, see Why does the first letter of the header key become uppercase when I use an HTTP trigger to invoke a function? | {"Header1": "value1", "Header2": "value1,value2"} |
queryParameters | Query parameters as key-value pairs. Multiple values for the same key are comma-separated. For a request to https://{url-id}.{region}.fcapp.run/example?key1=value1, the value is {"key1": "value1"}. | {"parameter1": "value1", "parameter2": "value1,value2"} |
requestContext | Additional request metadata, including request ID, timestamp, and caller identity. | — |
requestContext.accountId | ID of the Alibaba Cloud account that owns the function. | 123456********* |
requestContext.domainName | Domain name of the HTTP trigger. | <http-trigger-id>.<region-id>.fcapp.run |
requestContext.domainPrefix | Domain prefix of the HTTP trigger. | <http-trigger-id> |
requestContext.http | Detailed information about the HTTP request. | — |
requestContext.http.method | HTTP method. Valid values: GET, POST, PUT, HEAD, OPTIONS, PATCH, DELETE. | GET |
requestContext.http.path | Decoded request path. | /example |
requestContext.http.protocol | Request protocol. | HTTP/1.1 |
requestContext.http.sourceIp | Peer IP address (RemoteAddr) of the immediate TCP connection — the client's IP if the request is not proxied, or the last proxy's IP if proxied. To get the original client IP when the request passes through proxies, read the X-Forwarded-For header. For details, see How do I obtain the original IP address of a client when an HTTP trigger invokes a function that uses a built-in runtime? | 11.11.XX.XX |
requestContext.http.userAgent | Value of the User-Agent request header. | PostmanRuntime/7.32.3 |
requestContext.requestId | Request ID. Use this ID to trace invocation logs for the function. | 1-64f6cd87-************* |
requestContext.time | Request timestamp. | 2023-09-05T06:41:11Z |
requestContext.timeEpoch | Request timestamp in Unix time. | 1693896071895 |
Request mapping logic
Function Compute maps incoming HTTP requests to event objects as follows:
HTTP request headers →
event.headersQuery parameters →
event.queryParametersRequest context information →
event.requestContextPOST request body →
event.body
Base64 encoding
Function Compute checks the Content-Type header to decide whether to Base64-encode the request body:
No encoding (
isBase64Encoded: false):Content-Typeindicates a text format.Base64 encoding (
isBase64Encoded: true):Content-Typeindicates a binary or non-text format.
The following Content-Type values are treated as text (no encoding):
text/*application/jsonapplication/ld+jsonapplication/xhtml+xmlapplication/xmlapplication/atom+xmlapplication/javascript
All other Content-Type values result in Base64 encoding.
Request mapping examples
GET request
| HTTP request | Event object |
|---|---|
GET /?parameter1=value1¶meter2=value2 HTTP/1.1 | {"version": "v1", "rawPath": "/", "headers": {"Accept": "*/*", "User-Agent": "CurlHttpClient"}, "queryParameters": {"parameter1": "value1", "parameter2": "value2"}, "body": "", "isBase64Encoded": true, "requestContext": {"accountId": "1327************", "domainName": "example.cn-hangzhou.fcapp.run", "domainPrefix": "example", "requestId": "1-67aee50c-********-************", "time": "2025-02-14T06:39:08Z", "timeEpoch": "1739515148145", "http": {"method": "GET", "path": "/", "protocol": "HTTP/1.1", "sourceIp": "40.XX.XX.XX", "userAgent": "CurlHttpClient"}}} |
A GET request has no Content-Type header, so isBase64Encoded is true. To send the GET request above, run the following command, replacing https://example.cn-hangzhou.fcapp.run with your function URL:
curl -v "https://example.cn-hangzhou.fcapp.run?parameter1=value1¶meter2=value2"POST request
| HTTP request | Event object |
|---|---|
POST / HTTP/1.1Content-Type: application/json | {"version": "v1", "rawPath": "/", "headers": {"Accept": "*/*", "Content-Length": "20", "Content-Type": "application/json", "User-Agent": "curl/8.7.1"}, "queryParameters": {}, "body": "{\"message\": \"Hello\"}", "isBase64Encoded": false, "requestContext": {"accountId": "1327************", "domainName": "example.cn-hangzhou.fcapp.run", "domainPrefix": "example", "requestId": "1-67aee50c-********-************", "time": "2025-02-14T06:39:08Z", "timeEpoch": "1739515148145", "http": {"method": "POST", "path": "/", "protocol": "HTTP/1.1", "sourceIp": "40.XX.XX.XX", "userAgent": "CurlHttpClient"}}} |
Because Content-Type: application/json is a text format, isBase64Encoded is false. To send the POST request above, run the following command, replacing https://example.cn-hangzhou.fcapp.run with your function URL:
curl -v -H "Content-Type: application/json" -d '{"message": "Hello"}' "https://example.cn-hangzhou.fcapp.run"To force Base64 encoding, set Content-Type to application/x-www-form-urlencoded.
Response struct
Response struct format
Your function returns a response struct, which Function Compute parses and maps to an HTTP response:
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json",
"Custom-Header-1": "Custom Value"
},
"isBase64Encoded": false,
"body": "{\"message\":\"Hello FC!\"}"
}Response mapping logic
Function Compute maps your function's return value to an HTTP response based on the following rules.
If the function returns valid JSON with a `statusCode` field:
| JSON field | HTTP response |
|---|---|
statusCode | HTTP status code |
Content-Type in headers | Content-Type header (defaults to application/json if absent) |
body | Response body |
isBase64Encoded | Whether body is Base64-encoded (defaults to false if absent) |
If the function returns valid JSON without a `statusCode`, or non-JSON output:
Function Compute constructs the HTTP response with these defaults:
| Field | Default value |
|---|---|
statusCode | 200 |
Content-Type | application/json |
body | Function output |
isBase64Encoded | false |
Response mapping examples
The following table shows how function output is parsed into a response struct and mapped to the HTTP response the client receives.
| Function output | Parsed response struct | HTTP response (client receives) |
|---|---|---|
Hello World! | {"statusCode": 200, "body": "Hello World!", "headers": {"content-type": "application/json"}, "isBase64Encoded": false} | HTTP/1.1 200 OKContent-Disposition: attachmentContent-Length: 12Content-Type: application/jsonX-Fc-Request-Id: 1-64f6d6e7-e01edb1cce58240ed59b59d9Hello World! |
{"message": "Hello World!"} | {"statusCode": 200, "body": "{\"message\": \"Hello World!\"}", "headers": {"content-type": "application/json"}, "isBase64Encoded": false} | HTTP/1.1 200 OKContent-Disposition: attachmentContent-Length: 27Content-Type: application/jsonX-Fc-Request-Id: 1-64f6d867-7302fc1ac6338b6fd2adb782{"message": "Hello World!"} |
{"statusCode": 201, "headers": {"Content-Type": "application/json", "My-Custom-Header": "Custom Value"}, "body": {"message": "Hello, world!"}, "isBase64Encoded": false} | {"statusCode": 201, "headers": {"Content-Type": "application/json", "My-Custom-Header": "Custom Value"}, "body": {"message": "Hello, world!"}, "isBase64Encoded": false} | HTTP/1.1 201 OKContent-Disposition: attachmentContent-Length: 27Content-Type: application/jsonCustom-Header-1: Custom ValueX-Fc-Request-Id: 1-64f6dcb3-e787580749d3ba13b047ce14{"message": "Hello world!"} |
Base64 decoding
If the function returns valid JSON with isBase64Encoded: true, Function Compute Base64-decodes the body before mapping it to the HTTP response body. If decoding fails, Function Compute returns the raw body value without an error.
HTTP response headers
Function Compute automatically adds the X-Fc-Request-Id response header, which uniquely identifies the request. No other response headers are added automatically.
Custom response headers are supported with the following restrictions:
Headers starting with
X-Fc-are not allowed.The following headers are reserved and cannot be overridden:
connection,content-length,date,keep-alive,server,content-disposition. If any of these is returned as a custom header, Function Compute ignores it.
Error handling
Error behavior differs depending on how the function is invoked:
API invocation: Errors are returned in the response body with HTTP status code
200. For example, a PythonModuleNotFoundErrorreturns:{ "errorMessage": "Unable to import module 'index'", "errorType": "ImportModuleError", "stackTrace": [ "ModuleNotFoundError: No module named 'not_exist_module'" ] }Function URL invocation: Error details are hidden. Function Compute returns
Internal Server Errorwith HTTP status code502:HTTP/1.1 502 Bad Gateway Content-Disposition: attachment Content-Type: application/json X-Fc-Request-Id: 1-64f6df91-fe144d52e4fd27afe3d8dd6f Internal Server Error
Use the X-Fc-Request-Id value to look up the full error details in your function's invocation logs.
References
The following handler topics are relevant if you're writing code for a built-in runtime in Function Compute 3.0: