Search code examples
supabasesupabase-database

Supabase middleware for business logic


New to the supabase universe. Simple questions

Is there a way to setup middleware in supabase?. Can Supabase fulfill this?

  • Add business logic middleware when creating an entity
  • Add special validations (ie: validate a product has stock before purchase)
  • Restrict information depending on user roles (ie: admins can read additional entity attributes, but not common users).

Thanks


Solution

  • this is now solvable using Supabase's Edge Functions: https://supabase.com/docs/guides/functions

    There is an example here to solve "Restrict information depending on user roles" using Postgres' Row Level Security:

    https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts

    / Follow this setup guide to integrate the Deno language server with your editor:
    // https://deno.land/manual/getting_started/setup_your_environment
    // This enables autocomplete, go to definition, etc.
    
    import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
    import { supabaseClient } from '../_shared/supabaseClient.ts'
    import { corsHeaders } from '../_shared/cors.ts'
    
    console.log(`Function "select-from-table-with-auth-rls" up and running!`)
    
    serve(async (req: Request) => {
      // This is needed if you're planning to invoke your function from a browser.
      if (req.method === 'OPTIONS') {
        return new Response('ok', { headers: corsHeaders })
      }
    
      try {
        // Set the Auth context of the user that called the function.
        // This way your row-level-security (RLS) policies are applied.
        supabaseClient.auth.setAuth(req.headers.get('Authorization')!.replace('Bearer ', ''))
    
        const { data, error } = await supabaseClient.from('users').select('*')
        console.log({ data, error })
    
        return new Response(JSON.stringify({ data, error }), {
          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: 400,
        })
      }
    })