Supabase Edge Functions run Deno at the edge, giving you serverless APIs with direct database access and built-in auth.
Basic Edge Function
// supabase/functions/hello/index.ts
Deno.serve(async (req) => {
const { name } = await req.json()
return new Response(
JSON.stringify({ message: `Hello ${name}!` }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
Database Access
// supabase/functions/users/index.ts
import { createClient } from 'jsr:@supabase/supabase-js@2'
Deno.serve(async (req) => {
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
)
if (req.method === 'GET') {
const { data, error } = await supabase
.from('users')
.select('*')
.order('created_at', { ascending: false })
.limit(10)
return Response.json(data)
}
if (req.method === 'POST') {
const body = await req.json()
const { data, error } = await supabase
.from('users')
.insert(body)
.select()
.single()
return Response.json(data, { status: 201 })
}
})
Auth Integration
Deno.serve(async (req) => {
const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_ANON_KEY')!,
{
global: {
headers: { Authorization: req.headers.get('Authorization')! }
}
}
)
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
return Response.json({ error: 'Unauthorized' }, { status: 401 })
}
// User is authenticated — proceed
return Response.json({ user: user.email })
})
Webhooks & Integrations
// Process Stripe webhooks
Deno.serve(async (req) => {
const signature = req.headers.get('stripe-signature')
const body = await req.text()
const event = stripe.webhooks.constructEvent(
body, signature!, Deno.env.get('STRIPE_WEBHOOK_SECRET')!
)
if (event.type === 'checkout.session.completed') {
const session = event.data.object
await supabase
.from('orders')
.update({ status: 'paid' })
.eq('stripe_session_id', session.id)
}
return Response.json({ received: true })
})
Scheduled Functions (Cron)
-- In Supabase SQL editor
select cron.schedule(
'daily-cleanup',
'0 3 * * *',
$$
select net.http_post(
url := 'https://YOUR_PROJECT.supabase.co/functions/v1/cleanup',
headers := '{"Authorization": "Bearer YOUR_SERVICE_KEY"}'::jsonb
);
$$
);
Real-World Use Case
A solo developer needed a backend for their SaaS: auth, database, file storage, webhooks, and cron jobs. Traditional approach: Express + PostgreSQL + S3 + Redis + cron = 5 services, $100/month. Supabase: one project, edge functions for custom logic, free tier covers 500K function invocations/month. Time to MVP: one weekend.
Supabase Edge Functions are the serverless glue that makes Supabase a complete platform.
Build Smarter Data Pipelines
Need to scrape websites, extract APIs, or automate data collection? Check out my ready-to-use scrapers on Apify — no coding required.
Custom scraping solution? Email me at spinov001@gmail.com — fast turnaround, fair prices.
Top comments (0)