开发技巧
边缘函数入门指南
以下是开始开发边缘函数时的几点建议。
跳过授权检查
默认情况下,边缘函数需要在授权头中包含有效的JWT。如果您想在不进行授权检查的情况下使用边缘函数(常用于Stripe webhooks),可以在本地运行边缘函数时传递--no-verify-jwt
标志。
1supabase functions serve hello-world --no-verify-jwt
使用此标志时需谨慎,因为它将允许任何人在没有有效JWT的情况下调用您的边缘函数。Supabase客户端库会自动处理授权。
使用HTTP方法
边缘函数支持GET
、POST
、PUT、
PATCH、
DELETE和
OPTIONS`方法。可以根据请求的HTTP方法设计函数执行不同的操作。参考构建RESTful服务的示例了解如何在函数中处理不同的HTTP方法。
不支持HTML
不支持HTML内容。返回text/html
的GET
请求将被重写为text/plain
。
命名边缘函数
我们建议使用连字符命名函数,因为连字符是所有命名约定(snake_case、camelCase、PascalCase)中最符合URL规范的。
组织您的边缘函数
我们推荐开发"胖函数"(fat functions)。这意味着您应该开发少量的大型函数,而不是许多小型函数。在开发函数时,一个常见模式是需要在两个或多个函数之间共享代码。为此,您可以将任何共享代码存储在以下划线(_
)为前缀的文件夹中。我们还建议为单元测试使用单独的文件夹,包括函数名称后跟-test
后缀。
我们推荐以下文件夹结构:
12345678910111213141516└── 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验证和导入映射位置。
123[functions.hello-world]verify_jwt = falseimport_map = './import_map.json'
不使用TypeScript
当您创建新的边缘函数时,默认会使用TypeScript。但是,也可以使用纯JavaScript编写和部署边缘函数。
将您的函数保存为JavaScript文件(例如index.js
),然后按如下方式更新supabase/config.toml
:
entrypoint
仅在Supabase CLI版本1.215.0或更高版本中可用。
1[functions.hello-world]
其他配置项
entrypoint = './functions/hello-world/index.js' # 路径必须相对于 config.toml 文件
12345678910111213141516171819202122您可以使用任何 `.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编写。