Edge Functions
Fonctions serverless en TypeScript/Deno pour la logique métier côté serveur.
8.1Quand utiliser une Edge Function
| Cas d'usage | Pourquoi une Edge Function |
|---|---|
| Webhook Stripe | Vérifier la signature, traiter le paiement |
| Envoi d'emails | Clé API Resend/SendGrid cachée côté serveur |
| Appel API tierce | Ne pas exposer les clés API au navigateur |
| Génération PDF | Traitement lourd impossible côté client |
| CRON / Tâches planifiées | pg_cron + Edge Function pour nettoyage |
8.2Créer ta première Edge Function
Initialiser et créer une functionbash
# Installer le CLI Supabase
npm install -g supabase
# Se connecter
supabase login
# Lier au projet
supabase link --project-ref ton-project-id
# Créer une nouvelle Edge Function
supabase functions new hello-world
# → Crée supabase/functions/hello-world/index.tssupabase/functions/hello-world/index.tstypescript
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
serve(async (req: Request) => {
// Lire le body JSON
const { name } = await req.json()
// Retourner une réponse
return new Response(
JSON.stringify({ message: `Bonjour ${name} !` }),
{
headers: { 'Content-Type': 'application/json' },
status: 200,
},
)
})8.3Tester en local
Lancer en localbash
# Démarrer le serveur local (port 54321)
supabase functions serve hello-world --env-file .env.local
# Tester avec curl
curl -i --location --request POST \
'http://localhost:54321/functions/v1/hello-world' \
--header 'Content-Type: application/json' \
--data '{"name": "Apprenant"}'
# → {"message": "Bonjour Apprenant !"}8.4Déployer
Déployer en productionbash
# Déployer une function spécifique
supabase functions deploy hello-world
# Déployer toutes les functions
supabase functions deploy
# L'URL de production sera :
# https://<project-id>.supabase.co/functions/v1/hello-world8.5Appeler depuis le SDK
Appel depuis le frontendtypescript
// Le SDK gère automatiquement l'URL et l'authentification
const { data, error } = await supabase.functions.invoke('hello-world', {
body: { name: 'Apprenant' },
})
console.log(data) // { message: "Bonjour Apprenant !" }8.6Exemple concret : Webhook Stripe
supabase/functions/stripe-webhook/index.tstypescript
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import Stripe from 'https://esm.sh/stripe@14.0.0?target=deno'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!, {
apiVersion: '2023-10-16',
})
serve(async (req: Request) => {
const body = await req.text()
const sig = req.headers.get('stripe-signature')!
// Vérifier la signature du webhook
const event = stripe.webhooks.constructEvent(
body,
sig,
Deno.env.get('STRIPE_WEBHOOK_SECRET')!,
)
if (event.type === 'payment_intent.succeeded') {
const paymentIntent = event.data.object as Stripe.PaymentIntent
// Créer un client Supabase avec le service role (bypass RLS)
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!,
)
// Insérer la commande
await supabase.from('orders').insert({
user_id: paymentIntent.metadata.user_id,
tier: paymentIntent.metadata.tier,
amount: paymentIntent.amount,
stripe_payment_intent_id: paymentIntent.id,
})
}
return new Response(JSON.stringify({ received: true }), {
headers: { 'Content-Type': 'application/json' },
})
})8.7CORS
Gérer les CORS dans une Edge Functiontypescript
const corsHeaders = {
'Access-Control-Allow-Origin': 'https://monsite.com',
'Access-Control-Allow-Headers': 'authorization, content-type',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
}
serve(async (req: Request) => {
// Répondre aux requêtes preflight OPTIONS
if (req.method === 'OPTIONS') {
return new Response('ok', { headers: corsHeaders })
}
// Ta logique ici...
return new Response(
JSON.stringify({ success: true }),
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } },
)
})