函数计算支持HTTP触发器,配置HTTP触发器的函数可以通过HTTP请求被触发执行。此时函数可以看做一个Web Server,对HTTP请求进行处理,并将处理结果返回给调用端。本文介绍如何在函数计算控制台配置HTTP触发器并使用HTTP请求触发。
前提条件
背景信息
步骤一:创建触发器
步骤二:编写并部署代码
完成创建HTTP触发器后,您可以开始编写函数代码。
在函数详情页面,单击函数代码页签,在代码编辑器中编写代码,然后单击部署代码。
代码示例如下:
var getRawBody = require('raw-body')
module.exports.handler = function (request, response, context) {
// get request info
getRawBody(request, function (err, data) {
var params = {
path: request.path,
queries: request.queries,
headers: request.headers,
method: request.method,
body: data,
url: request.url,
clientIP: request.clientIP,
}
// you can deal with your own logic here
// set response
var respBody = new Buffer.from(JSON.stringify(params));
// var respBody = new Buffer( )
response.setStatusCode(200)
response.setHeader('content-type', 'application/json')
response.send(respBody)
})
};
# -*- coding: utf-8 -*-
import json
HELLO_WORLD = b"Hello world!\n"
def handler(environ, start_response):
request_uri = environ['fc.request_uri']
response_body = {
'uri':environ['fc.request_uri'],
'method':environ['REQUEST_METHOD']
}
# do something here
status = '200 OK'
response_headers = [('Content-type', 'text/json')]
start_response(status, response_headers)
# Python2
return [json.dumps(response_body)]
# Python3 tips: When using Python3, the str and bytes types cannot be mixed.
# Use str.encode() to go from str to bytes
# return [json.dumps(response_body).encode()]
<?php
use RingCentral\Psr7\Response;
function handler($request, $context): Response{
/*
$body = $request->getBody()->getContents();
$queries = $request->getQueryParams();
$method = $request->getMethod();
$headers = $request->getHeaders();
$path = $request->getAttribute("path");
$requestURI = $request->getAttribute("requestURI");
$clientIP = $request->getAttribute("clientIP");
*/
return new Response(
200,
array(
"custom_header1" => "v1",
"custom_header2" => ["v2", "v3"],
),
"hello world"
);
}
注意 对于异步调用,请在函数链路中做好异步结果回调处理。具体操作,请参见结果回调。
步骤三:测试函数
方式一:使用控制台测试函数
在函数详情页面,单击函数代码页签。
- 同步调用
单击测试函数。
- 异步调用
单击测试函数右侧的
图标,选择异步调用,然后单击测试函数。
执行完成后,在函数代码页签,您可以看到执行结果。
方式二:使用浏览器测试函数
将HTTP触发器URL输入浏览器地址栏,按回车键执行。
执行完成后,浏览器中会返回执行结果文件。
HTTP触发器URL的获取方式如下所示:
- 针对新建HTTP触发器,推荐您使用函数计算为新建HTTP触发器分配的子域名作为HTTP触发器URL。
子域名格式如下:
<subdomain>.<region_id>.fcapp.run/[action?queries]
示例如下:
funcname-svcname-khljsjksld.cn-shanghai.fcapp.run/action?hello=world
说明 您也可以按照存量HTTP触发器URL组装规则组装HTTP触发器URL。但是,函数计算推荐您使用函数计算为新建HTTP触发器分配的子域名subdomain
作为HTTP触发器URL进行函数测试,能有效避免404
报错,也能避免代码中耦合函数计算的服务名称和函数名称,增强代码的可移植性。关于404
报错的更多信息,请参见当我使用浏览器或cURL方式访问函数时出现404怎么办?。 - 针对存量HTTP触发器,您可以按照组装规则组装HTTP触发器URL。
组装规则如下:
<account_id>.<region_id>.fc.aliyuncs.com/<version>/proxy/<serviceName>/<functionName>/[action?queries]
示例如下:
164901546557****.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/serviceName/functionName/action?hello=world
参数说明
参数 说明 account_id 阿里云账号ID。 您可以在安全设置中获取您的账号ID。如果您是RAM用户,将鼠标移至控制台右上角的头像处可以看到您的阿里云账号ID。
region_id 函数计算服务所在的地域。 version 函数计算的API版本。 serviceName 服务名称。 functionName 函数名称。 action 自定义的请求路径。 queries 查询参数。
方式三:使用cURL测试函数
- 同步调用
在命令行执行如下命令,执行完成后会返回执行结果。
curl -v https://http-***.cn-shenzhen.fcapp.run/$path
- 异步调用
在命令行执行如下命令,执行完成后会返回函数计算接收请求的结果。其中状态码
202
表示请求成功,其余表示请求出现错误,关于错误码的解释,请参见常见问题(错误排查)。curl -v -H "X-Fc-Invocation-Type: Async" https://http-***.cn-shenzhen.fcapp.run/$path
(可选)使用API网关保护HTTP函数
默认情况下,函数计算不会对HTTP请求进行身份验证,支持匿名访问HTTP函数,即任何人都可以发送HTTP请求调用您的函数。为了防止非法用户访问您的函数,引起不必要的资源浪费或安全隐患,您可以开启身份认证的同时将HTTP函数与API网关进行对接,利用API网关的IP访问控制插件、JWT认证插件或BasicAuth插件等保护您的HTTP函数。
完成以上步骤后,您可以通过自己的域名访问HTTP函数。您还可以创建以下插件,并将其绑定到您的API,保护您的HTTP函数。
常见问题
为什么HTTP函数无法执行?
- 如果是您新创建的触发器,会有10s左右的缓存更新时间,请稍后再试。
- 请检查函数的入口函数是否正确,HTTP函数与普通函数的入口函数不同。不同语言的HTTP函数请参见以下文档:
为什么函数无法结束?
请检查是否调用返回函数。
- Node.js需调用
response.send()
。 - Python需调用
return
。 - PHP需调用
return new Response()
。 - Java需调用
HttpServletResponse
- C#需调用
return
。 - Custom Runtime以各语言示例为准。
错误排查
错误主要分为以下两种:
- 请求错误是指发送的Request不符合标准,在Response里报错状态码为4xx。
- 函数错误即编写的函数有问题,会报5xx状态码。
错误类型 | X-Fc-Error-Type | HTTP状态码 | 原因分析 | 是否计费 |
---|---|---|---|---|
请求错误 | FcCommonError | 400 | 您的请求超过Request限制项的限制。更多信息,请参见使用限制。 | 否 |
FcCommonError | 400 | 调用需要身份认证的函数的Request没有传入Date信息或Authorization信息。 | 否 | |
FcCommonError | 403 | 调用需要身份认证的函数的Request的签名错误,即Authorization不正确。由于Date参与签名计算,且超过15 min,签名失效,一种常见的原因是使用需要访问认证的HTTP触发器,Request header中发送的Date据当前时间超过15 min,导致签名失效。 | 否 | |
FcCommonError | 403 | 您的Request请求使用了HTTP触发器中未配置的请求方法。例如,HTTP触发器中的请求方法只配置了GET方法,却发送POST方法的HTTP请求。 | 否 | |
FcCommonError | 404 | 向没有设置HTTP触发器的函数发送HTTP请求。 | 否 | |
用户流控 | FcCommonError | 429 | 用户被流控,可减小并发量或者联系函数计算开发团队提高并发度。 | 否 |
函数错误 | UnhandledInvocationError | 502 | 函数的返回值超过Response限制项的限制。更多信息,请参见使用限制。 | 是 |
UnhandledInvocationError | 502 | 函数代码有语法错误或者异常。 | 是 | |
UnhandledInvocationError | 502 | 向未使用HTTP入口函数的函数发送HTTP请求。 | 是 | |
系统错误 | FcCommonError | 500 | 函数计算系统错误,可重试解决。 | 否 |
系统流控 | FcCommonError | 503 | 函数计算系统流控。可用指数退避方式重试。 | 否 |
如果问题还未能解决,请联系我们。
更多信息
除了函数计算控制台,您还可通过以下方式配置触发器:
- 通过Serverless Devs工具配置触发器。更多操作,请参见Serverless Devs。
- 通过SDK配置触发器。更多操作,请参见SDK列表。
如需对创建的触发器进行修改或删除,具体操作,请参见触发器管理。