पाठ 16 / 25

Edge Functions

Deno functions with secrets.

Server code without a server

Edge Functions are TypeScript functions running on a Deno-based runtime, deployed with the CLI and invoked over HTTPS or with supabase.functions.invoke(). They are the place for secrets (payment or email API keys), webhooks from third parties and privileged work. By default they expect a valid JWT in the Authorization header. Inside, SUPABASE_URL, the anon key and the service role key are available as environment variables; add your own with supabase secrets set. Check the docs for current variable names as key naming evolves.

Logic beyond the client

Edge Functions run server-side TypeScript; triggers, cron and extensions put more work inside Postgres.

Three ideas: edge functions, triggers and scheduled jobs, pgvector.
Figure 6.1 — Client, edge function, database triggers and jobs.

A function that acts as the caller

supabase/functions/hello/index.ts.

import { createClient } from 'npm:@supabase/supabase-js@2'

Deno.serve(async (req) => {
  // forward the caller's JWT so RLS applies to their queries
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_ANON_KEY')!,
    { global: { headers: { Authorization: req.headers.get('Authorization')! } } }
  )
  const { data: { user } } = await supabase.auth.getUser()
  const { name } = await req.json()
  return new Response(JSON.stringify({ message: `Hello ${name}`, userId: user?.id }), {
    headers: { 'Content-Type': 'application/json' },
  })
})

// client:
// const { data, error } = await supabase.functions.invoke('hello', { body: { name: 'Asha' } })

Use the service role only after checking the caller

Verify who is calling and what they may do before creating a service-role client inside a function, because that client bypasses RLS entirely.

त्वरित जाँच: Why forward the Authorization header to the client inside an edge function?

  • To bypass RLS
  • To make the function faster
  • So queries run as the calling user and RLS applies
  • Because Deno requires it for imports
Answer

So queries run as the calling user and RLS applies — Act as the user unless you need elevated rights.