A multi-AI agent platform that helps you level up your development skills and ace your interview preparation to secure your dream job.
Launch Xperto-AISupabase Functions are a powerful feature that allows developers to create serverless, event-driven APIs with ease. These functions run at the edge, providing low-latency responses and seamless integration with other Supabase services. In this guide, we'll explore how to leverage Supabase Functions to build robust APIs for your applications.
Let's start by creating a simple "Hello, World!" function:
Install the Supabase CLI if you haven't already:
npm install -g supabase
Initialize a new Supabase project:
supabase init
Create a new function:
supabase functions new hello-world
Open the newly created supabase/functions/hello-world/index.ts
file and add the following code:
import { serve } from "https://deno.land/std@0.168.0/http/server.ts" serve(async (req) => { const { name } = await req.json() const data = { message: `Hello ${name}!`, } return new Response( JSON.stringify(data), { headers: { "Content-Type": "application/json" } }, ) })
Deploy your function:
supabase functions deploy hello-world
Now you have a basic API endpoint that accepts a JSON payload with a name
field and responds with a greeting!
Supabase Functions can handle various HTTP methods. Let's expand our previous example to support both GET and POST requests:
import { serve } from "https://deno.land/std@0.168.0/http/server.ts" serve(async (req) => { if (req.method === 'GET') { return new Response( JSON.stringify({ message: "Hello, World!" }), { headers: { "Content-Type": "application/json" } }, ) } else if (req.method === 'POST') { const { name } = await req.json() return new Response( JSON.stringify({ message: `Hello, ${name}!` }), { headers: { "Content-Type": "application/json" } }, ) } else { return new Response( JSON.stringify({ error: "Method not allowed" }), { status: 405, headers: { "Content-Type": "application/json" } }, ) } })
This function now handles GET requests with a default greeting and POST requests with a personalized greeting based on the provided name.
Supabase Functions can be easily secured using JWT authentication. Here's how to modify your function to require authentication:
First, update your supabase/config.toml
file to enable JWT verification:
[functions] [functions.hello-world] verify_jwt = true
Modify your function to use the authenticated user's information:
import { serve } from "https://deno.land/std@0.168.0/http/server.ts" import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' serve(async (req) => { // Create a Supabase client with the Auth context of the logged in user. const supabaseClient = createClient( Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', { global: { headers: { Authorization: req.headers.get('Authorization')! } } } ) // Now we can get the session or user object const { data: { user }, } = await supabaseClient.auth.getUser() // And we can run queries in the context of our authenticated user const { data, error } = await supabaseClient.from('users').select('*') return new Response( JSON.stringify({ user, data }), { headers: { 'Content-Type': 'application/json' } }, ) })
This function now requires a valid JWT token and uses it to fetch the authenticated user's information and perform database queries.
Supabase Functions can directly interact with your Supabase database. Let's create a function that fetches and returns a list of items from a hypothetical items
table:
import { serve } from "https://deno.land/std@0.168.0/http/server.ts" import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' serve(async (req) => { const supabaseClient = createClient( Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', { global: { headers: { Authorization: req.headers.get('Authorization')! } } } ) const { data, error } = await supabaseClient .from('items') .select('*') .order('created_at', { ascending: false }) .limit(10) if (error) { return new Response( JSON.stringify({ error: error.message }), { status: 500, headers: { 'Content-Type': 'application/json' } }, ) } return new Response( JSON.stringify({ items: data }), { headers: { 'Content-Type': 'application/json' } }, ) })
This function fetches the 10 most recently created items from the items
table and returns them as a JSON response.
Proper error handling and logging are crucial for maintaining and debugging your APIs. Here's an example of how to implement robust error handling:
import { serve } from "https://deno.land/std@0.168.0/http/server.ts" import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' serve(async (req) => { try { const supabaseClient = createClient( Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', { global: { headers: { Authorization: req.headers.get('Authorization')! } } } ) const { data, error } = await supabaseClient .from('items') .select('*') .order('created_at', { ascending: false }) .limit(10) if (error) throw error return new Response( JSON.stringify({ items: data }), { headers: { 'Content-Type': 'application/json' } }, ) } catch (error) { console.error('Error in function:', error.message) return new Response( JSON.stringify({ error: 'An unexpected error occurred' }), { status: 500, headers: { 'Content-Type': 'application/json' } }, ) } })
This implementation uses a try-catch block to handle any unexpected errors and logs them for debugging purposes.
Supabase Functions provide a powerful and flexible way to build serverless APIs. By leveraging these functions, you can create scalable, secure, and efficient backend services that integrate seamlessly with other Supabase features. As you continue to explore Supabase, you'll discover even more ways to enhance your APIs and build robust applications.
09/11/2024 | Supabase
09/11/2024 | Supabase
09/11/2024 | Supabase
09/11/2024 | Supabase
09/11/2024 | Supabase
09/11/2024 | Supabase
09/11/2024 | Supabase
09/11/2024 | Supabase