边缘函数

开发技巧

边缘函数入门指南


以下是开始开发边缘函数时的几点建议。

跳过授权检查

默认情况下,边缘函数需要在授权头中包含有效的JWT。如果您想在不进行授权检查的情况下使用边缘函数(常用于Stripe webhooks),可以在本地运行边缘函数时传递--no-verify-jwt标志。

1
supabase functions serve hello-world --no-verify-jwt

使用此标志时需谨慎,因为它将允许任何人在没有有效JWT的情况下调用您的边缘函数。Supabase客户端库会自动处理授权。

使用HTTP方法

边缘函数支持GETPOST、PUTPATCHDELETEOPTIONS`方法。可以根据请求的HTTP方法设计函数执行不同的操作。参考构建RESTful服务的示例了解如何在函数中处理不同的HTTP方法。

命名边缘函数

我们建议使用连字符命名函数,因为连字符是所有命名约定(snake_case、camelCase、PascalCase)中最符合URL规范的。

组织您的边缘函数

我们推荐开发"胖函数"(fat functions)。这意味着您应该开发少量的大型函数,而不是许多小型函数。在开发函数时,一个常见模式是需要在两个或多个函数之间共享代码。为此,您可以将任何共享代码存储在以下划线(_)为前缀的文件夹中。我们还建议为单元测试使用单独的文件夹,包括函数名称后跟-test后缀。

我们推荐以下文件夹结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
└── supabase ├── functions ├── import_map.json # 用于跨函数使用的顶级导入映射 ├── _shared ├── supabaseAdmin.ts # 使用SERVICE_ROLE密钥的Supabase客户端 └── supabaseClient.ts # 使用ANON密钥的Supabase客户端 └── cors.ts # 可重用的CORS头 ├── function-one # 使用连字符命名函数 └── index.ts └── function-two └── index.ts └── tests └── function-one-test.ts └── function-two-test.ts ├── migrations └── config.toml

使用config.toml

可以通过config.toml文件设置单个函数的配置,如JWT验证导入映射位置

1
2
3
[functions.hello-world]verify_jwt = falseimport_map = './import_map.json'

不使用TypeScript

当您创建新的边缘函数时,默认会使用TypeScript。但是,也可以使用纯JavaScript编写和部署边缘函数。

将您的函数保存为JavaScript文件(例如index.js),然后按如下方式更新supabase/config.toml

1
[functions.hello-world]

其他配置项

entrypoint = './functions/hello-world/index.js' # 路径必须相对于 config.toml 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
您可以使用任何 `.ts`、`.js`、`.tsx`、`.jsx` 或 `.mjs` 文件作为函数的 `entrypoint`。### 错误处理`supabase-js` 库提供了几种错误类型,可用于处理调用边缘函数时可能发生的错误:```jsimport { FunctionsHttpError, FunctionsRelayError, FunctionsFetchError } from '@supabase/supabase-js'const { data, error } = await supabase.functions.invoke('hello', { headers: { 'my-custom-header': 'my-custom-header-value' }, body: { foo: 'bar' },})if (error instanceof FunctionsHttpError) { const errorMessage = await error.context.json() console.log('函数返回错误', errorMessage)} else if (error instanceof FunctionsRelayError) { console.log('中继错误:', error.message)} else if (error instanceof FunctionsFetchError) { console.log('获取错误:', error.message)}

数据库函数 vs 边缘函数

对于数据密集型操作,我们推荐使用数据库函数,这些函数在数据库内执行,可以通过REST和GraphQL API远程调用。

对于需要低延迟的用例,我们推荐使用边缘函数,这些函数全球分布式部署,可以用TypeScript编写。