DEV Community

Alex Spinov
Alex Spinov

Posted on

Supabase Edge Functions Have a Free API You Should Know About

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' } }
  )
})
Enter fullscreen mode Exit fullscreen mode

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 })
  }
})
Enter fullscreen mode Exit fullscreen mode

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 })
})
Enter fullscreen mode Exit fullscreen mode

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 })
})
Enter fullscreen mode Exit fullscreen mode

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
  );
  $$
);
Enter fullscreen mode Exit fullscreen mode

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)