Supabase Edge Functions : Logique Serverless avec Deno

Les Edge Functions Supabase permettent d’exécuter du code TypeScript/JavaScript côté serveur, proche de l’utilisateur, sans gérer d’infrastructure. Basées sur Deno, elles sont idéales pour les webhooks, les paiements Stripe, les emails transactionnels et toute logique métier sensible.

Pour les fondations, consultez notre guide complet Supabase. Pour les fonctions PostgreSQL côté base de données, voir SQL, triggers et fonctions Supabase. Pour l’Auth dans vos fonctions, voir Supabase Auth. Pour appeler vos fonctions depuis Next.js, voir Supabase avec Next.js. Pour les appels depuis React, voir Supabase avec React. Pour les requêtes REST alternatives, voir API REST Supabase.

Pourquoi Utiliser les Edge Functions ?

  • 🔒 Logique sensible : clés API, secrets, logique de pricing
  • Performance : exécutées en bordure réseau
  • 🔌 Intégrations tierces : Stripe, SendGrid, Twilio, IA
  • 📨 Webhooks : réception de webhooks sécurisés
  • 🤖 IA : OpenAI, Anthropic, Gemini côté serveur

Créer une Edge Function

# Créer la fonction
supabase functions new ma-fonction

# Structure créée:
supabase/
└── functions/
    └── ma-fonction/
        └── index.ts

Structure de base

// supabase/functions/ma-fonction/index.ts
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  try {
    const { name } = await req.json()
    
    return new Response(
      JSON.stringify({ message: `Bonjour, ${name}!` }),
      {
        headers: { ...corsHeaders, 'Content-Type': 'application/json' },
        status: 200,
      }
    )
  } catch (error) {
    return new Response(
      JSON.stringify({ error: error.message }),
      { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 500 }
    )
  }
})

Accéder à Supabase depuis une Edge Function

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

serve(async (req) => {
  const authHeader = req.headers.get('Authorization')
  
  // Client avec le JWT de l'utilisateur (respecte la RLS)
  const supabaseUser = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_ANON_KEY')!,
    { global: { headers: { Authorization: authHeader! } } }
  )
  
  // Client admin (bypass RLS)
  const supabaseAdmin = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  )
  
  const { data: { user } } = await supabaseUser.auth.getUser()
  if (!user) {
    return new Response('Unauthorized', { status: 401 })
  }
  
  const { data } = await supabaseAdmin
    .from('orders')
    .select('*')
    .eq('user_id', user.id)
  
  return new Response(JSON.stringify(data))
})

Cas d’Usage : Paiement Stripe

import Stripe from 'https://esm.sh/stripe@13.0.0?target=deno'

const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!, {
  apiVersion: '2023-10-16',
})

serve(async (req) => {
  // ... auth check ...
  
  const { priceId } = await req.json()
  
  const session = await stripe.checkout.sessions.create({
    customer_email: user.email,
    payment_method_types: ['card'],
    line_items: [{ price: priceId, quantity: 1 }],
    mode: 'subscription',
    success_url: `${Deno.env.get('SITE_URL')}/success`,
    cancel_url: `${Deno.env.get('SITE_URL')}/pricing`,
    metadata: { user_id: user.id }
  })
  
  return new Response(
    JSON.stringify({ url: session.url }),
    { headers: { 'Content-Type': 'application/json' } }
  )
})

Variables d’Environnement et Déploiement

# Définir des secrets
supabase secrets set STRIPE_SECRET_KEY=sk_live_xxx
supabase secrets set RESEND_API_KEY=re_xxx

# Tester en local
supabase functions serve ma-fonction

# Déployer en production
supabase functions deploy ma-fonction

Appeler une Edge Function depuis le Client

// Depuis le client Supabase
const { data, error } = await supabase.functions.invoke('ma-fonction', {
  body: { name: 'Jean' }
})

// Ou via fetch standard
const response = await fetch(
  'https://[ref].supabase.co/functions/v1/ma-fonction',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${session?.access_token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name: 'Jean' })
  }
)

👉 Articles du guide Supabase

Cet article fait partie du Guide Complet Supabase 2026. Retrouvez les autres articles :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *