Supabase Edge Functions 开发指南

摘要

本文档旨在为使用 Supabase Edge Functions 的开发者提供一份全面的开发指南。Edge Functions 是一种在离用户更近的边缘服务器上运行的 TypeScript 函数,具有低延迟和高响应速度的优势。它们基于现代的 Deno 运行时环境,这与传统的 Node.js 后端开发在环境、安全性和依赖管理上有着显著的区别。本文档将首先介绍 Deno 的核心概念,然后深入探讨编写 Edge Functions 时的关键注意事项、最佳实践和工作流程。


Deno - Edge Functions 的核心运行环境

要精通 Supabase Edge Functions,首先必须理解其基础------Deno。Deno 是由 Node.js 创造者 Ryan Dahl 开发的一个现代、安全的 JavaScript 和 TypeScript 运行时,旨在修复 Node.js 的一些历史设计缺陷。

1.1 Deno 是什么?

  • 一个运行时:和 Node.js 一样,它让 JavaScript/TypeScript 代码可以在服务器端运行。
  • Node.js 的继任者:它被设计为 Node.js 的一个更现代、更安全的替代品。

1.2 Deno 与 Node.js 的核心区别

特性 (Feature) Deno Node.js
安全性 默认沙箱,需通过命令行标志显式授权文件、网络等权限 默认拥有与启动进程相同的权限
TypeScript 支持 原生支持 ,可直接运行 .ts 文件,无需任何配置 需要手动安装编译器 (tsc) 和配置
模块管理 URL 导入 (ESM) ,无 node_modules 文件夹 使用 npm/yarnpackage.json,依赖存储在 node_modules
内置工具 非常全面 (代码格式化、检查、测试、打包等) 依赖庞大且分散的第三方工具生态
核心 API 拥抱 Web 标准 (如 fetch, Request, Response, URL) 拥有大量自有 API (如 require, fs, http 模块)
生态系统 正在快速成长,但相对较小 极其庞大和成熟

理解这些区别至关重要,因为它们直接影响了您编写、管理和部署 Edge Functions 的方式。


编写 Supabase Edge Functions 的关键注意事项

基于 Deno 的特性,开发 Edge Functions 时需要遵循一套新的规则和最佳实践。

2.1 核心概念与运行环境

  • 没有 npm,拥抱 URL 导入 您的所有依赖都必须通过 URL 引入。这是 Deno 的核心机制。

    TypeScript 复制代码
    // 正确方式: 直接从 URL 导入
    import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
  • 使用 import_map.json 管理依赖 为了代码整洁和版本管理,最佳实践是使用 supabase/import_map.json 文件来定义依赖别名。

    JSON 复制代码
    // supabase/import_map.json
    {
      "imports": {
        "supabase-js": "https://esm.sh/@supabase/supabase-js@2",
        "stripe": "https://esm.sh/stripe@11.1.0?target=deno"
      }
    }

    在代码中即可像传统方式一样导入:

    TypeScript 复制代码
    import { createClient } from "supabase-js";
  • 原生 TypeScript 与 Web API 直接编写 .ts 文件,无需编译步骤。函数内可以直接使用 fetch, Request, Response 等浏览器标准 API,开发体验与编写 Service Worker 类似。

2.2 安全性 (Security)

安全性是 Edge Functions 的生命线。

  • 用户身份验证与 RLS 客户端调用函数时,其 JWT 会通过 Authorization 请求头传递。您必须在函数中解析此 Token,并用它来初始化 Supabase 客户端,这样才能确保数据库的行级安全策略(RLS)对该用户的操作生效。

    TypeScript 复制代码
    const authHeader = req.headers.get('Authorization')!;
    
    // 以用户的身份创建客户端,所有操作将遵循该用户的 RLS
    const supabaseClient = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_ANON_KEY') ?? '',
      { global: { headers: { Authorization: authHeader } } }
    );
    
    // 此查询将受到 RLS 的限制
    const { data, error } = await supabaseClient.from('profiles').select('*');
  • 谨慎使用服务角色密钥 (service_role key) 此密钥可以绕过所有 RLS 策略 ,拥有数据库的完全权限。绝对禁止将其硬编码在代码中。

    • 正确做法:通过 Supabase Secrets 进行管理。

      Bash 复制代码
      # 本地设置
      supabase secrets set MY_SERVICE_KEY=your_secret_key
      # 生产环境在项目面板中设置
    • 在代码中通过环境变量安全访问:

      TypeScript 复制代码
      // 创建一个拥有管理员权限的客户端
      const supabaseAdmin = createClient(
        Deno.env.get('SUPABASE_URL') ?? '',
        Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '' // 安全获取
      );
  • 处理 CORS (跨域资源共享) 如果函数需要被浏览器前端调用,必须正确处理 CORS。这通常包括响应 OPTIONS 预检请求和在主请求的响应中添加 Access-Control-Allow-Origin 等头部信息。

2.3 性能与限制

  • 无状态 (Stateless) :每次函数调用都在一个全新的、隔离的环境中执行。两次调用之间不共享内存或本地状态。持久化数据需依赖 Supabase 数据库或其他外部服务。
  • 冷启动 (Cold Starts) :函数长时间未被调用后,首次调用会有轻微的启动延迟。保持函数代码和依赖轻量化是关键。
  • 执行时间限制:函数有最大执行时间(通常为 60 秒),不适合长时间运行的批处理任务。
  • 资源限制:存在内存使用上限和部署包大小限制。
  • 无文件系统访问:无法像在传统服务器上那样读写本地文件系统。

2.4 开发与部署工作流

Supabase CLI 是您的核心开发工具。

  1. 启动本地环境:

    Bash 复制代码
    supabase start

    这会在本地运行一个完整的 Supabase 服务栈。

  2. 本地开发与测试:

    Bash 复制代码
    supabase functions serve <function_name>

    此命令会启动一个本地服务器来运行您的函数,并支持热重载,极大提升开发效率。

  3. 部署到生产环境:

    Bash 复制代码
    supabase functions deploy <function_name>
  4. 日志与调试:

    • 本地 : 日志 (console.log) 会直接输出到运行 serve 命令的终端。
    • 生产: 在 Supabase 项目的 Dashboard 中查看函数的调用日志。

相关推荐
Mintopia4 小时前
⚡当 Next.js 遇上实时通信:Socket.io 与 Pusher 双雄传
前端·后端·全栈
ZhengEnCi4 小时前
ObjectUtils.isEmpty 完全指南-从入门到精通的 Java 空值判断利器
java·后端
tangdou3690986554 小时前
可怕!我的Nodejs系统因为日志打印了Error 对象就崩溃了😱 Node.js System Crashed Because of Logging
前端·javascript·后端
廖广杰4 小时前
Oauth2.0 授权码模式认证流程
后端
BlackQid4 小时前
深入理解指针Part4——字符、数组与函数指针变量
c++·后端
Postkarte不想说话4 小时前
FreeBSD配置Jails
后端
但求无bug4 小时前
Java中计算两个日期的相差时间
后端
小傅哥4 小时前
新项目完结,Ai Agent 智能体、拖拉拽编排!
前端·后端
廖广杰4 小时前
java虚拟机-如何通过GC日志判断晋升失败(Promotion Failed)
后端