跳到主要内容

Web 函数

Web 函数是云开发提供的新一代云函数运行环境,专门针对 Web 服务场景进行了优化。相比于事件函数,Web 函数支持标准的 HTTP 请求响应模式,用户可以快速将现有的 Web 服务迁移到 Serverless 架构上。

前置条件

  • 已开通云开发服务
  • 已创建云开发环境
  • 本地已安装 CloudBase CLI

运行机制

Web 函数与事件函数的运行机制对比:

特性事件函数Web 函数
触发方式事件驱动HTTP 请求
执行环境每次调用创建新环境支持环境复用
连接方式短连接支持长连接
端口监听无需监听端口监听 9000 端口
适用场景事件处理、定时任务Web 服务、API 接口

核心特性

Web 函数具备以下核心能力:

  • HTTP 请求处理:直接接收和处理标准 HTTP 请求
  • SSE 支持:支持 Server-Sent Events 实时推送
  • WebSocket 支持:支持 WebSocket 长连接通信
  • 文件上传下载:支持文件的上传和下载操作
  • 框架兼容:兼容 Express.js、Koa.js 等主流 Web 框架

适用场景

Web 函数特别适用于以下场景:

  • RESTful API 服务:构建标准的 REST API 接口
  • Web 应用迁移:将现有 Web 应用迁移到 Serverless 架构
  • 微服务架构:将单体应用拆分为多个独立的微服务
  • 实时通信:基于 SSE 或 WebSocket 的实时数据推送
  • 文件处理服务:提供文件上传、下载、转换等功能

开发方式

云开发 Web 函数支持两种开发方式:

1. 框架模式

使用 @cloudbase/functions-framework 框架,保持函数式编程风格:

// 使用函数式写法
exports.main = async function(event, context) {
// 业务逻辑
return {
statusCode: 200,
body: JSON.stringify({ message: 'Hello World' })
};
};

2. 原生模式

编写完整的 HTTP 服务代码,监听 9000 端口:

// 使用 Express.js 框架
const express = require('express');
const app = express();

app.get('/', (req, res) => {
res.json({ message: 'Hello World' });
});

app.listen(9000, () => {
console.log('Server running on port 9000');
});

使用 Functions Framework 开发

推荐使用 @cloudbase/functions-framework 框架进行开发,它提供了更简洁的函数式编程体验。

项目结构

my-web-function/
├── scf_bootstrap # 启动脚本(必需)
├── package.json # 项目配置
└── index.js # 函数代码

启动脚本

创建 scf_bootstrap 文件:

#!/bin/bash
node node_modules/@cloudbase/functions-framework/bin/tcb-ff.js --port=9000 --logDirname=/tmp/logs --interceptOutput=false --extendedContextKey=X-Cloudbase-Context
注意

scf_bootstrap 文件需要具有可执行权限,在 Linux/macOS 系统中使用 chmod +x scf_bootstrap 命令设置权限。

依赖配置

package.json 文件:

{
"name": "my-web-function",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"@cloudbase/functions-framework": "^1.14.0"
}
}

基础示例

index.js 文件:

exports.main = async function(event, context) {
const { method, path, headers, body } = event;

// 处理不同的 HTTP 方法
switch (method) {
case 'GET':
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: 'Hello from Web Function',
path,
timestamp: new Date().toISOString()
})
};

case 'POST':
return {
statusCode: 201,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: 'Data received',
data: JSON.parse(body || '{}')
})
};

default:
return {
statusCode: 405,
body: JSON.stringify({ error: 'Method not allowed' })
};
}
};

SSE 实时推送示例

Web 函数支持 Server-Sent Events,可以实现实时数据推送:

exports.main = async function(event, context) {
// 切换到 SSE 模式
const sse = context.sse();

// 监听连接关闭事件
sse.on('close', () => {
console.log('SSE connection closed');
});

// 发送实时数据
if (!sse.closed) {
// 发送文本数据
sse.send({ data: 'Hello from SSE function' });

// 发送 JSON 数据
sse.send({
data: JSON.stringify({
type: 'notification',
message: 'New message received',
timestamp: Date.now()
})
});

// 发送 Buffer 数据
sse.send({ data: Buffer.from('Binary data message') });
}

return '';
};

部署配置

使用 CLI 部署

  1. 安装依赖:
npm install
  1. 创建 cloudbaserc.json 配置文件:
{
"envId": "your-env-id",
"functions": [
{
"name": "webFunction",
"type": "web",
"source": "./",
"runtime": "Nodejs16.13",
"memorySize": 256,
"timeout": 60,
"environment": {
"NODE_ENV": "production"
}
}
]
}
  1. 部署函数:
cloudbase functions:deploy webFunction

通过云开发平台部署

  1. 登录 云开发平台
  2. 选择目标环境,进入「云函数」页面
  3. 点击「新建函数」,选择「Web 函数」类型
  4. 上传代码包或在线编辑代码
  5. 配置函数参数并部署

函数调用

HTTP API 调用

Web 函数部署成功后,可通过 HTTP API 进行调用:

curl -L 'https://{envId}.api.tcloudbasegateway.com/v1/functions/{functionName}?webfn=true' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
-d '{}'
重要提示

调用 Web 函数时必须在 URL 中添加 webfn=true 参数,否则调用会失败。

获取访问令牌

调用 Web 函数需要携带访问令牌,获取方式请参考:Access Token

最佳实践

1. 错误处理

exports.main = async function(event, context) {
try {
// 业务逻辑
const result = await processRequest(event);

return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result)
};
} catch (error) {
console.error('Function error:', error);

return {
statusCode: 500,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
error: 'Internal server error',
message: error.message
})
};
}
};

2. 参数验证

function validateRequest(event) {
const { method, body } = event;

if (method === 'POST') {
const data = JSON.parse(body || '{}');

if (!data.name || !data.email) {
throw new Error('Missing required fields: name, email');
}

// 邮箱格式验证
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(data.email)) {
throw new Error('Invalid email format');
}
}
}

3. 环境变量使用

exports.main = async function(event, context) {
const config = {
apiKey: process.env.API_KEY,
dbUrl: process.env.DATABASE_URL,
debug: process.env.NODE_ENV === 'development'
};

if (!config.apiKey) {
return {
statusCode: 500,
body: JSON.stringify({ error: 'Missing API key configuration' })
};
}

// 使用配置进行业务处理
};

注意事项

重要说明
  • Web 函数必须监听 9000 端口
  • 使用 Functions Framework 时需要包含 scf_bootstrap 启动脚本
  • 函数代码包大小限制为 50MB(压缩后)
  • 单次请求超时时间最长为 900 秒
  • 支持的运行时:Node.js 12.16、14.18、16.13、18.15

与事件函数的差异

Web 函数的 eventcontext 参数与事件函数存在差异:

  • event 对象:包含 HTTP 请求的完整信息(method、path、headers、body 等)
  • context 对象:提供 SSE 支持等 Web 特有功能
  • 环境变量:运行时环境变量可能有所不同

常见问题

如何处理文件上传?

exports.main = async function(event, context) {
const { method, headers, body } = event;

if (method === 'POST' && headers['content-type']?.includes('multipart/form-data')) {
// 处理文件上传逻辑
// 注意:需要解析 multipart 数据
return {
statusCode: 200,
body: JSON.stringify({ message: 'File uploaded successfully' })
};
}

return {
statusCode: 400,
body: JSON.stringify({ error: 'Invalid request' })
};
};

如何实现跨域支持?

exports.main = async function(event, context) {
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
};

// 处理预检请求
if (event.method === 'OPTIONS') {
return {
statusCode: 200,
headers: corsHeaders,
body: ''
};
}

// 正常请求处理
return {
statusCode: 200,
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Success' })
};
};

相关文档