跳到主要内容

编写 HTTP 云函数

「HTTP 云函数」是专为 Web 服务场景设计的云函数类型,提供了原生 HTTP 支持、实时通信能力和多函数路由等特性。

💡 关于基础能力:本文聚焦 HTTP 云函数的特有能力(HTTP 处理、SSE、WebSocket、函数路由等)。如需了解云函数的通用能力(依赖安装、环境变量、时区处理等),请参考 编写普通云函数

快速开始

第一步:创建函数入口文件

创建 index.js 作为 HTTP 函数入口文件:

exports.main = function (event, context) {
return `Hello world!`;
};

第二步:创建启动脚本(必需)

在项目根目录创建 scf_bootstrap 文件(无扩展名),内容为启动项目的命令:

#!/bin/bash
node index.js

启动脚本详情请参考:启动文件说明

项目结构

完整的项目目录结构如下:

my-web-function/
├── scf_bootstrap # 启动脚本(必需,无扩展名)
├── package.json # 项目配置
├── index.js # 函数入口文件
└── node_modules/ # 依赖包(npm install 后生成)

参考资源

💡 提示:HTTP 云函数支持「函数路由」功能,允许多个子函数运行在同一个实例上。详见 HTTP 云函数路由

函数结构与参数

基本结构

exports.main = function (event, context) {
// 函数逻辑
};

或使用异步函数:

exports.main = async function (event, context) {
// 异步函数逻辑
};

💡 类型定义支持:云开发提供 @cloudbase/functions-typings@v-1 类型定义包,辅助 TypeScript 代码编写。详见 使用 TypeScript 编写函数 章节。

event 参数

event 参数包含 HTTP 请求数据,内容根据请求类型不同而变化:

  • POST 请求:请求体(body)内容
  • multipart/form-data:表单数据
  • PUT 请求:上传的文件
  • 无请求体时:空对象 {}

context 参数

context 参数提供函数执行的上下文信息:

属性/方法类型说明
eventIDstring事件唯一标识,用于关联请求上下文
eventTypestring事件类型,固定为 http
timestampnumber请求时间戳
httpContexthttpBasisHTTP 请求的相关信息
extendedContextRecord<string, unknown>扩展上下文信息(环境信息等)

httpBasis 接口

属性类型说明
urlstring本次请求的完整 URL
httpMethodstringHTTP 方法(如 GETPOST
headersIncomingHttpHeadersHTTP 请求头

extendedContext 扩展信息

// import { TcbExtendedContext } from '@cloudbase/functions-typings'
interface TcbExtendedContext {
envId: string; // 环境 ID
uin: string; // 请求的 UIN
source: string; // 请求来源(如 wx)
serviceName: string; // 服务名称
serviceVersion: string; // 服务版本
authMethod?: string; // 认证方式:UNAUTHORIZED | CAM_TC3 | TCB_OAUTH2_B | TCB_OAUTH2_C | WX_SERVER_AUTH
userType?: string; // 用户类型:NONE | B_SIDE_USER | C_SIDE_USER
isAdministrator?: boolean; // C 端用户是否为管理员
accessToken?: string; // 调用请求时的 AccessToken
userId?: string; // 请求的用户 ID
tmpSecret?: {
// 临时凭证
secretId: string;
secretKey: string;
token: string;
};
wechatContext?: {
// 微信上下文信息
callId: string; // 微信调用 ID
source: string; // 请求来源
appId: string; // 小程序 AppID
openId: string; // 用户 OpenID
unionId: string; // 用户 UnionID
fromOpenId?: string; // 环境资源共享时的 fromOpenID
fromUnionId?: string; // 环境资源共享时的 fromUnionID
fromAppId?: string; // 环境资源共享时的 fromAppID
};
}

函数路由

HTTP云函数支持web框架,因此可以通过对应的web框架进行实现多路由

也可以基于 @cloudbase/functions-framework 框架实现。它支持将一个大函数拆分成多个子函数,并通过请求路径将不同的请求路由到不同的处理函数。

请参考:HTTP 云函数路由

实时通信能力

HTTP 云函数提供两种实时通信方式:「SSE(Server-Sent Events)」和「WebSocket」。

SSE(Server-Sent Events)

「SSE」是一种基于 HTTP 的服务端推送技术,支持单向实时数据流传输(服务端 → 客户端)。

核心特点

  • 基于 HTTP 协议,兼容性好,默认支持无需配置
  • 客户端自动重连
  • 实现简单,资源占用低
  • 适合 AI 对话流式输出、实时日志、进度更新等场景

详细文档:完整的 SSE 使用指南、消息格式规范、常见问题解决,请参考 SSE 协议支持

WebSocket

「WebSocket」是一种全双工通信协议,支持双向实时通信(服务端 ↔ 客户端)。

核心特点

  • 双向实时通信,持久连接,低延迟
  • 需要在控制台开启 WebSocket 协议支持
  • 服务器必须监听 9000 端口
  • 适合实时聊天、协作编辑、游戏服务器等场景

详细文档:完整的 WebSocket 使用指南、控制台配置步骤、使用限制、常见问题解决,请参考 WebSocket 协议支持

技术选型对比

特性SSEWebSocket
通信方式单向(服务端→客户端)双向(服务端↔客户端)
协议HTTPWebSocket 协议
实现复杂度简单相对复杂
配置要求无需配置需控制台开启
自动重连否(需手动实现)
适用场景单向数据推送实时双向通信

选择建议

  • 只需服务端推送数据(如 AI 对话、日志、进度)→ 选择 SSE
  • 需要双向实时通信(如聊天、协作、游戏)→ 选择 WebSocket

使用 TypeScript 编写函数代码

类型定义安装

npm install @cloudbase/functions-typings@v-1

基本类型定义

import { TcbEventFunction } from '@cloudbase/functions-typings';

TcbEventFunction 是一个泛型类型:

TcbEventFunction<EventT = unknown, ResultT extends ReturnT = void>
  • EventT:定义 event 参数类型
  • ResultT:定义函数返回值类型

定义 event 参数类型

JSON 请求体

type JsonEvent = { a: number; b: string; c: boolean };

export const main: TcbEventFunction<JsonEvent> = function (event, context) {
event.a; // number
event.b; // string
};

FormData 文件上传

import { TcbEventFunction, File } from '@cloudbase/functions-typings';

type FormEvent = { str: string; file: File };

export const main: TcbEventFunction<FormEvent> = function (event, context) {
event.str;
event.file.filepath;
};

定义返回值类型

普通响应

export const main: TcbEventFunction<void, string> = function (event, context) {
return 'done.';
};

集成响应

import { TcbEventFunction, IntegrationResponse } from '@cloudbase/functions-typings';

export const main: TcbEventFunction<void, IntegrationResponse<string>> = function (event, context) {
return {
statusCode: 200,
headers: {},
body: 'Hello world',
};
};

异步函数

export const main: TcbEventFunction<void, Promise<string>> = async function (event, context) {
return new Promise((resolve) => {
setImmediate(() => {
resolve('done.');
});
});
};

完整示例

import { TcbEventFunction, File, IntegrationResponse } from '@cloudbase/functions-typings';

// GET 无请求体
export const main: TcbEventFunction = function (event, context) {};

// JSON 请求体
type JsonEvent = { a: number; b: string };
export const main: TcbEventFunction<JsonEvent> = function (event, context) {
event.a;
event.b;
};

// FormData 上传
type FormEvent = { str: string; file: File };
export const main: TcbEventFunction<FormEvent> = function (event, context) {
event.str;
event.file.filepath;
};

// 二进制流
export const main: TcbEventFunction<Buffer> = function (event, context) {
event.byteLength;
};

// 访问 Context 信息
export const main: TcbEventFunction<void, void> = function (event, context) {
context.extendedContext?.envId;
context.extendedContext?.userId;
};

// 普通响应
export const main: TcbEventFunction<void, string> = function (event, context) {
return 'done.';
};

// 集成响应
export const main: TcbEventFunction<void, IntegrationResponse<string>> = function (event, context) {
return {
statusCode: 200,
headers: {},
body: '',
};
};

// 异步函数
export const main: TcbEventFunction<void, Promise<string>> = async function (event, context) {
return new Promise((resolve) => {
setImmediate(() => {
resolve('done.');
});
});
};

// SSE
export const main: TcbEventFunction<void, Promise<string>> = async function (event, context) {
const sse = context.sse?.();

if (sse && !sse.closed) {
sse.on('close', () => {
console.log('sse closed');
});

sse.send({ data: 'hello from sse function' });

sse.send([{ data: 'This is the first message.' }, { data: 'This is the second message.' }]);
}
return '';
};

// WebSocket
export const main: TcbEventFunction = async function (event, context) {
if (context.ws) {
context.ws.on('open', (msg) => {
console.log('open: ', msg);
});
context.ws.on('error', (msg) => {
console.log('error: ', msg);
});
context.ws.on('close', (msg) => {
console.log('close: ', msg);
});
context.ws.on('message', (msg) => {
console.log('message: ', msg);
});
context.ws.send('hello from websocket function');
}
};
main.handleUpgrade = async function (context) {
return {
allowWebSocket: true,
};
};

项目组织结构

基于 TypeScript 的多函数项目

.
├── README.md
├── Dockerfile
├── src/
│ ├── func-a/
│ │ ├── built/ # 编译后代码
│ │ ├── src/ # TypeScript 源码
│ │ ├── package.json
│ │ ├── cloudbase-functions.json
│ │ └── tsconfig.json
│ └── func-b/
│ ├── built/
│ ├── src/
│ ├── package.json
│ └── tsconfig.json
├── package.json
└── tsconfig.json

项目结构参考:TypeScript 模板项目

单函数项目

.
├── README.md
├── built/ # 编译后代码
├── src/ # TypeScript 源码
├── Dockerfile
├── package.json
├── cloudbase-functions.json
└── tsconfig.json

💡 提示:JavaScript 项目无需 srcbuilttsconfig.json 等目录和文件。

相关文档