```html
Supabase est rapidement devenu une alternative open-source puissante à Firebase, offrant aux développeurs une suite d'outils construits autour d'une base de données PostgreSQL. À la base, Supabase offre une couche API instantanée et en temps réel au-dessus de votre base de données, accélérant considérablement le développement du backend. Ce guide fournit un aperçu complet de la façon d'exploiter l'API Supabase, et couvre tout, de la configuration initiale et des opérations de base à la sécurité, la personnalisation et la sécurité des types.
Vous voulez une plateforme intégrée, tout-en-un, pour que votre équipe de développeurs travaille ensemble avec une productivité maximale ?
Apidog répond à toutes vos demandes et remplace Postman à un prix beaucoup plus abordable !

1. Introduction : Qu'est-ce que l'API Supabase ?
Contrairement au développement backend traditionnel où vous pourriez passer beaucoup de temps à créer des points de terminaison REST ou GraphQL pour interagir avec votre base de données, Supabase génère automatiquement une API sécurisée et performante pour vous. Lorsque vous créez une table dans votre base de données Supabase PostgreSQL, Supabase utilise PostgREST, un outil open-source, pour introspecter votre schéma de base de données et fournir les points de terminaison RESTful correspondants.
Principaux avantages :
- Backend instantané : Obtenez des points de terminaison d'API fonctionnels dès que vous définissez votre schéma de base de données.
- Capacités en temps réel : Abonnez-vous aux modifications de la base de données via WebSockets.
- Basé sur PostgreSQL : Tirez parti de la puissance, de la flexibilité et de la maturité de PostgreSQL, y compris des fonctionnalités telles que la sécurité au niveau des lignes (RLS).
- Méthodes d'interaction multiples : Interagissez via REST, GraphQL (pris en charge par la communauté) ou les bibliothèques clientes de Supabase (JavaScript, Python, Dart, etc.).
- Extensibilité : Créez des fonctions sans serveur personnalisées (Edge Functions) pour une logique ou des intégrations complexes.
Ce guide se concentre principalement sur l'API REST et son interaction via les bibliothèques clientes, ainsi que sur les fonctions Supabase Edge.
2. Premiers pas avec l'API Supabase
Le moyen le plus simple de comprendre l'API Supabase est de se lancer. Supposons que vous ayez un projet Supabase configuré (sinon, visitez supabase.com et créez-en un gratuitement) et que vous ayez créé une table simple, par exemple profiles
:
-- Create a table for public profiles
create table profiles (
id uuid references auth.users not null primary key,
updated_at timestamp with time zone,
username text unique,
avatar_url text,
website text,
constraint username_length check (char_length(username) >= 3)
);
-- Set up Row Level Security (RLS)
-- See https://supabase.com/docs/guides/auth/row-level-security for more details.
alter table profiles
enable row level security;
create policy "Public profiles are viewable by everyone." on profiles
for select using (true);
create policy "Users can insert their own profile." on profiles
for insert with check (auth.uid() = id);
create policy "Users can update own profile." on profiles
for update using (auth.uid() = id);
-- This trigger automatically creates a profile entry when a new user signs up via Supabase Auth.
-- See https://supabase.com/docs/guides/auth/managing-user-data#using-triggers for more details.
create function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, username)
values (new.id, new.raw_user_meta_data->>'username');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
(Remarque : L'exemple ci-dessus utilise profiles
, en accord avec les exemples standard de Supabase. Le concept s'applique également à une table todos
ou à toute autre table que vous créez.)
Trouver vos informations d'identification API :
Chaque projet Supabase est livré avec des informations d'identification API uniques :
- URL du projet : Votre point de terminaison Supabase unique (par exemple,
https://<your-project-ref>.supabase.co
). - Clés API : Se trouvent dans le tableau de bord de votre projet Supabase sous
Project Settings
>API
.
- Clé
anon
(publique) : Cette clé peut être utilisée en toute sécurité dans les applications côté client (comme les navigateurs ou les applications mobiles). Elle s'appuie sur la sécurité au niveau des lignes (RLS) pour contrôler l'accès aux données. - Clé
service_role
: Il s'agit d'une clé secrète avec des privilèges administratifs complets, contournant RLS. N'exposez jamais cette clé dans le code côté client. Utilisez-la uniquement dans des environnements de serveur sécurisés (comme les serveurs backend ou les fonctions sans serveur).
Interaction avec l'API (à l'aide de la bibliothèque cliente Supabase JS) :
Supabase fournit des bibliothèques clientes pour simplifier les interactions avec l'API. Voici comment vous utiliseriez la bibliothèque JavaScript (supabase-js
) :
// 1. Import and initialize the client
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://<your-project-ref>.supabase.co'
const supabaseAnonKey = '<your-anon-key>'
const supabase = createClient(supabaseUrl, supabaseAnonKey)
// 2. Fetch data (SELECT *)
async function getProfiles() {
const { data, error } = await supabase
.from('profiles')
.select('*')
if (error) console.error('Error fetching profiles:', error)
else console.log('Profiles:', data)
}
// 3. Insert data (INSERT)
async function createProfile(userId, username) {
const { data, error } = await supabase
.from('profiles')
.insert([
{ id: userId, username: username, updated_at: new Date() },
])
.select() // Return the inserted data
if (error) console.error('Error creating profile:', error)
else console.log('Created Profile:', data)
}
// 4. Update data (UPDATE)
async function updateProfileUsername(userId, newUsername) {
const { data, error } = await supabase
.from('profiles')
.update({ username: newUsername, updated_at: new Date() })
.eq('id', userId) // Only update where id matches
.select()
if (error) console.error('Error updating profile:', error)
else console.log('Updated Profile:', data)
}
// 5. Delete data (DELETE)
async function deleteProfile(userId) {
const { data, error } = await supabase
.from('profiles')
.delete()
.eq('id', userId) // Only delete where id matches
if (error) console.error('Error deleting profile:', error)
// Note: Delete often returns minimal data on success unless .select() is used *before* .delete() on some versions/setups.
else console.log('Profile deleted successfully')
}
// Example Usage (assuming you have a user ID)
// getProfiles();
// createProfile('some-uuid-v4', 'new_user');
// updateProfileUsername('some-uuid-v4', 'updated_username');
// deleteProfile('some-uuid-v4');
Ce démarrage rapide démontre les opérations CRUD (Create, Read, Update, Delete) fondamentales à l'aide de la bibliothèque cliente, qui appelle en interne l'API REST.
3. L'API REST Supabase générée automatiquement
Bien que les bibliothèques clientes soient pratiques, il est crucial de comprendre l'API REST sous-jacente générée par PostgREST.
Structure du point de terminaison de l'API :
L'URL de base de l'API REST est généralement : https://<your-project-ref>.supabase.co/rest/v1/
Des points de terminaison sont automatiquement créés pour vos tables :
GET /rest/v1/your_table_name
: Récupère les lignes de la table.POST /rest/v1/your_table_name
: Insère de nouvelles lignes dans la table.PATCH /rest/v1/your_table_name
: Met à jour les lignes existantes dans la table.DELETE /rest/v1/your_table_name
: Supprime les lignes de la table.
Authentification :
Les requêtes d'API doivent inclure votre clé API dans l'en-tête apikey
et généralement un en-tête Authorization
contenant Bearer <your-api-key>
(souvent la même clé anon
pour les requêtes côté client, ou la clé service_role
pour le côté serveur).
apikey: <your-anon-or-service-role-key>
Authorization: Bearer <your-anon-or-service-role-key>
Opérations courantes (à l'aide d'exemples curl
) :
Reproduisons les exemples précédents à l'aide de curl
directement sur l'API REST. Remplacez les espaces réservés en conséquence.
Récupérer des données (GET) :
curl 'https://<ref>.supabase.co/rest/v1/profiles?select=*' \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>"
Insérer des données (POST) :
curl 'https://<ref>.supabase.co/rest/v1/profiles' \
-X POST \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>" \
-H "Content-Type: application/json" \
-H "Prefer: return=representation" \# Optional: Returns the inserted row(s) \
-d '{ "id": "some-uuid", "username": "rest_user" }'
Mettre à jour les données (PATCH) : (Mettre à jour le profil où le nom d'utilisateur est 'rest_user')
curl 'https://<ref>.supabase.co/rest/v1/profiles?username=eq.rest_user' \
-X PATCH \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>" \
-H "Content-Type: application/json" \
-H "Prefer: return=representation" \
-d '{ "website": "https://example.com" }'
Supprimer des données (DELETE) : (Supprimer le profil où le nom d'utilisateur est 'rest_user')
curl 'https://<ref>.supabase.co/rest/v1/profiles?username=eq.rest_user' \
-X DELETE \
-H "apikey: <anon-key>" \
-H "Authorization: Bearer <anon-key>"
Filtrage, sélection, ordre, pagination :
L'API REST prend en charge des requêtes puissantes via les paramètres d'URL :
- Sélection de colonnes :
?select=column1,column2
- Filtrage (égalité) :
?column_name=eq.value
(par exemple,?id=eq.some-uuid
) - Filtrage (autres opérateurs) :
gt
(supérieur à),lt
(inférieur à),gte
,lte
,neq
(différent de),like
,ilike
(like insensible à la casse),in
(par exemple,?status=in.(active,pending)
) - Classement :
?order=column_name.asc
ou?order=column_name.desc
(ajouter.nullsfirst
ou.nullslast
si nécessaire) - Pagination :
?limit=10&offset=0
(récupérer les 10 premiers),?limit=10&offset=10
(récupérer les 10 suivants)
Documentation de l'API générée automatiquement :
L'une des fonctionnalités les plus utiles de Supabase est la documentation de l'API générée automatiquement disponible directement dans le tableau de bord de votre projet.
- Accédez à votre projet Supabase.
- Cliquez sur l'icône API Docs (ressemble généralement à
<>
) dans la barre latérale gauche. - Sélectionnez une table sous "Tables et vues".
- Vous verrez une documentation détaillée pour les points de terminaison REST spécifiques à cette table, notamment :
- Exemples de requêtes (Bash/
curl
, JavaScript). - Filtres, sélecteurs et modificateurs disponibles.
- Descriptions des colonnes et des types de données.
Cette documentation interactive est inestimable pour comprendre comment structurer vos appels d'API.
4. Génération de types pour un développement amélioré à l'aide de l'API Supabase
Pour les projets utilisant TypeScript ou d'autres langages typés, Supabase fournit un moyen de générer des définitions de types directement à partir de votre schéma de base de données. Cela apporte des avantages importants :
- Sécurité des types : Détectez les erreurs au moment de la compilation plutôt qu'au moment de l'exécution.
- Autocomplétion : Obtenez des suggestions intelligentes dans votre éditeur de code pour les noms de tables, les noms de colonnes et les paramètres de fonction.
- Amélioration de la maintenabilité : Les types servent de documentation vivante pour vos structures de données.
Génération de types à l'aide de Supabase CLI :
- Installez Supabase CLI : Suivez les instructions sur
https://supabase.com/docs/guides/cli
. - Connectez-vous :
supabase login
- Liez votre projet :
supabase link --project-ref <your-project-ref>
(Exécutez ceci dans le répertoire de votre projet local). Vous devrez peut-être fournir un mot de passe de base de données. - Générez des types :
supabase gen types typescript --linked > src/database.types.ts
# Or specify project-id if not linked or in a different context
# supabase gen types typescript --project-id <your-project-ref> > src/database.types.ts
Cette commande inspecte le schéma de base de données de votre projet Supabase lié et génère un fichier TypeScript (database.types.ts
dans cet exemple) contenant des interfaces pour vos tables, vues et arguments/types de retour de fonction.
Utilisation des types générés :
Vous pouvez ensuite importer ces types dans le code de votre application :
import { createClient } from '@supabase/supabase-js'
// Import the generated types
import { Database } from './database.types' // Adjust path as needed
const supabaseUrl = 'https://<your-project-ref>.supabase.co'
const supabaseAnonKey = '<your-anon-key>'
// Provide the Database type to createClient
const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey)
// Now you get type safety and autocompletion!
async function getSpecificUserProfile(username: string) {
// Autocompletes table names ('profiles')
const { data, error } = await supabase
.from('profiles')
// Autocompletes column names ('id', 'username', 'website')
.select('id, username, website')
// Type checks the value against the column type
.eq('username', username)
.single() // Expects a single result or null
if (error) {
console.error('Error fetching profile:', error)
return null;
}
// 'data' is now correctly typed based on your select query
if (data) {
console.log(`User ID: ${data.id}, Website: ${data.website}`);
// console.log(data.non_existent_column); // <-- TypeScript error!
}
return data;
}
La génération de types est une pratique fortement recommandée pour un développement d'applications robuste avec Supabase.
5. Création d'itinéraires d'API Supabase personnalisés avec les fonctions Edge
Bien que l'API REST générée automatiquement couvre les opérations CRUD standard, vous aurez souvent besoin d'une logique côté serveur personnalisée pour :
- Intégration avec des services tiers (par exemple, Stripe, Twilio).
- Effectuer des calculs complexes ou des agrégations de données.
- Exécuter une logique qui nécessite des privilèges élevés (clé
service_role
) sans exposer la clé au client. - Appliquer des règles commerciales complexes.
Les fonctions Edge de Supabase fournissent un moyen de déployer des fonctions TypeScript basées sur Deno globalement à la périphérie, près de vos utilisateurs.
Création d'une fonction Edge :
- Initialiser les fonctions (si ce n'est pas déjà fait) :
supabase functions new hello-world
(exécuter dans le répertoire de votre projet lié). Cela crée un fichiersupabase/functions/hello-world/index.ts
.
Écrivez le code de votre fonction :
// supabase/functions/hello-world/index.ts
import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' // Use appropriate std version
serve(async (req) => {
// You can access request headers, method, body etc. from 'req'
console.log(`Request received for: ${req.url}`);
// Example: Accessing Supabase DB from within the function
// Note: Requires setting up the Supabase client *inside* the function
// Use environment variables for secrets!
// import { createClient } from '@supabase/supabase-js'
// const supabaseAdmin = createClient(
// Deno.env.get('SUPABASE_URL') ?? '',
// Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
// )
// const { data: users, error } = await supabaseAdmin.from('profiles').select('*').limit(10);
const data = {
message: `Hello from the Edge!`,
// users: users // Example if fetching data
}
return new Response(
JSON.stringify(data),
{ headers: { 'Content-Type': 'application/json' } },
)
})
Déployez la fonction :
supabase functions deploy hello-world --no-verify-jwt
# Use --no-verify-jwt for publicly accessible functions
# Omit it or set --verify-jwt=true to require a valid Supabase Auth JWT
Invoquez la fonction :
Vous pouvez appeler des fonctions déployées via des requêtes HTTP POST (ou GET, selon la logique de la fonction) vers leur point de terminaison unique :https://<your-project-ref>.supabase.co/functions/v1/hello-world
En utilisant curl
:
curl -X POST 'https://<ref>.supabase.co/functions/v1/hello-world' \
-H "Authorization: Bearer <user-jwt-if-required>" \
-H "Content-Type: application/json" \
-d '{"name": "Functions"}' # Optional request body
Ou en utilisant le client Supabase JS :
const { data, error } = await supabase.functions.invoke('hello-world', {
method: 'POST', // or 'GET', etc.
body: { name: 'Functions' }
})
Les fonctions Edge sont un outil puissant pour étendre les capacités de votre backend Supabase au-delà des simples opérations de base de données.
6. Clés API et sécurisation de votre API Supabase
Comprendre les clés API et mettre en œuvre des mesures de sécurité appropriées est non négociable.
Récapitulatif des clés API :
- Clé
anon
(publique) : Pour une utilisation côté client. Repose entièrement sur la sécurité au niveau des lignes (RLS) pour la protection des données. - Clé
service_role
: Pour une utilisation côté serveur UNIQUEMENT. Contourne RLS, accordant un accès complet à la base de données. Protégez cette clé avec soin.
Le rôle crucial de la sécurité au niveau des lignes (RLS) :
RLS est la pierre angulaire de la sécurité Supabase lors de l'utilisation de la clé anon
. Il vous permet de définir des stratégies de contrôle d'accès affinées directement dans la base de données PostgreSQL. Les stratégies sont essentiellement des règles SQL qui déterminent quelles lignes un utilisateur peut afficher, insérer, mettre à jour ou supprimer en fonction de son statut authentifié, de son ID d'utilisateur, de son rôle ou d'autres critères.
Activation de RLS :
Par défaut, RLS est désactivé sur les nouvelles tables. Vous devez l'activer pour toute table à laquelle vous avez l'intention d'accéder côté client à l'aide de la clé anon
.
-- Enable RLS on the 'profiles' table
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- IMPORTANT: If no policies are defined after enabling RLS,
-- access is implicitly denied for all operations (except the table owner).
Création de stratégies RLS :
Les stratégies définissent la clause USING
(pour l'accès en lecture comme SELECT
, UPDATE
, DELETE
) et la clause WITH CHECK
(pour l'accès en écriture comme INSERT
, UPDATE
).
Exemple 1 : Autoriser les utilisateurs connectés à lire tous les profils :
CREATE POLICY "Allow authenticated read access"
ON profiles FOR SELECT
USING ( auth.role() = 'authenticated' );
Exemple 2 : Autoriser les utilisateurs à afficher uniquement leur propre profil :
CREATE POLICY "Allow individual read access"
ON profiles FOR SELECT
USING ( auth.uid() = id ); -- Assumes 'id' column matches the user's UUID from Supabase Auth
Exemple 3 : Autoriser les utilisateurs à mettre à jour uniquement leur propre profil :
CREATE POLICY "Allow individual update access"
ON profiles FOR UPDATE
USING ( auth.uid() = id ) -- Specifies which rows can be targeted for update
WITH CHECK ( auth.uid() = id ); -- Ensures any *new* data still matches the condition
Exemple 4 : Autoriser les utilisateurs à insérer leur propre profil :
CREATE POLICY "Allow individual insert access"
ON profiles FOR INSERT
WITH CHECK ( auth.uid() = id );
Vous pouvez afficher, créer et gérer des stratégies RLS directement dans le tableau de bord Supabase sous Authentication
> Policies
.
Principes de sécurité clés :
- Activez toujours RLS sur les tables accessibles via la clé
anon
. - Définissez des stratégies explicites pour
SELECT
,INSERT
,UPDATE
,DELETE
selon les besoins. Commencez par des stratégies restrictives et ouvrez l'accès avec soin. - N'exposez jamais la clé
service_role
dans le code côté client ou dans des environnements non sécurisés. - Utilisez les fonctions Edge pour les opérations nécessitant des privilèges élevés ou une logique côté serveur complexe, protégeant votre clé
service_role
dans les variables d'environnement sécurisées de la fonction. - Examinez régulièrement vos stratégies RLS pour vous assurer qu'elles répondent aux exigences de sécurité de votre application.
7. Mappage des concepts SQL à l'API Supabase (SQL vers API)
Si vous connaissez SQL, il est utile de comprendre comment les opérations SQL courantes se mappent à l'API Supabase (à la fois REST et les bibliothèques clientes).
SELECT * FROM my_table;
- REST :
GET /rest/v1/my_table?select=*
- JS :
supabase.from('my_table').select('*')
SELECT column1, column2 FROM my_table WHERE id = 1;
- REST :
GET /rest/v1/my_table?select=column1,column2&id=eq.1
- JS :
supabase.from('my_table').select('column1, column2').eq('id', 1)
INSERT INTO my_table (column1, column2) VALUES ('value1', 'value2');
- REST :
POST /rest/v1/my_table
avec le corps JSON{"column1": "value1", "column2": "value2"}
- JS :
supabase.from('my_table').insert({ column1: 'value1', column2: 'value2' })
UPDATE my_table SET column1 = 'new_value' WHERE id = 1;
- REST :
PATCH /rest/v1/my_table?id=eq.1
avec le corps JSON{"column1": "new_value"}
- JS :
supabase.from('my_table').update({ column1: 'new_value' }).eq('id', 1)
DELETE FROM my_table WHERE id = 1;
- REST :
DELETE /rest/v1/my_table?id=eq.1
- JS :
supabase.from('my_table').delete().eq('id', 1)
Jointures : Bien que la syntaxe JOIN
SQL directe ne soit pas utilisée dans les appels REST de base, vous pouvez récupérer des données connexes en utilisant :
- Relations de clé étrangère :
?select=*,related_table(*)
récupère les données des tables connexes définies par les clés étrangères. - JS :
supabase.from('my_table').select('*, related_table(*)')
- RPC (appels de procédure distante) : Pour les jointures ou la logique complexes, créez une fonction PostgreSQL et appelez-la via l'API.
-- Example SQL function
CREATE FUNCTION get_user_posts(user_id uuid)
RETURNS TABLE (post_id int, post_content text) AS $$
SELECT posts.id, posts.content
FROM posts
WHERE posts.author_id = user_id;
$$ LANGUAGE sql;
- REST :
POST /rest/v1/rpc/get_user_posts
avec le corps JSON{"user_id": "some-uuid"}
- JS :
supabase.rpc('get_user_posts', { user_id: 'some-uuid' })
8. Utilisation de schémas personnalisés avec l'API Supabase
Par défaut, les tables que vous créez dans l'éditeur SQL Supabase résident dans le schéma public
. Pour une meilleure organisation, un espace de noms ou une gestion des autorisations, vous souhaiterez peut-être utiliser des schémas PostgreSQL personnalisés.
Création d'un schéma personnalisé :
CREATE SCHEMA private_schema;
Création de tables dans un schéma personnalisé :
CREATE TABLE private_schema.sensitive_data (
id serial primary key,
payload jsonb
);
Accès aux tables dans des schémas personnalisés via l'API :
La couche PostgREST de Supabase détecte automatiquement les tables dans des schémas autres que public
.
- API REST : Les points de terminaison de l'API restent les mêmes (
/rest/v1/table_name
), mais PostgREST expose les tables d'autres schémas par défaut. Vous devrez peut-être gérer l'accès via les rôles et les autorisations dans PostgreSQL si vous souhaitez un contrôle d'accès au niveau du schéma affiné au-delà de RLS standard. En cas de collision de noms (même nom de table danspublic
et un autre schéma), vous devrez peut-être une configuration spécifique ou utiliser RPC. Consultez la documentation PostgREST pour gérer la visibilité du schéma si nécessaire. - Bibliothèques clientes : Les bibliothèques clientes fonctionnent de manière transparente. Vous référencez simplement le nom de la table comme d'habitude :
// Accessing a table in 'private_schema' (assuming RLS/permissions allow)
const { data, error } = await supabase
.from('sensitive_data') // No need to prefix with schema name here
.select('*')
.eq('id', 1);
Sup