Supabase Tutorial in Italiano: Le operazioni CRUD e prima introduzione a PostgreSQL

In questo articolo, con video in allegato, osserveremo come effettuare le prime operazioni CRUD su un database PostgreSQL integrato nella piattaforma Supabase.

Autore: Giacomo Verde • 26/08/2026
CategorySupabase Tutorial/Course
Core StackJavaScript, SupabaseJS, Supabase
Read Time5 min

Di cosa parlo in questo video

Il video parte con lo spiegare cosa sono le operazioni CRUD (creazione, lettura, aggiornamento ed eliminazione dei dati) e come possiamo creare un client, una minuscola applicazione a file HTML singolo, la quale ci consentirà di interagire con le tabelle del database, in particolare quella dei prodotti products.

Nel video ignoro per scopi didattici la parte di sicurezza del database, che gestiremo con RLS (row level security), argomento che approfondirò in prossimi video/articoli sul mio canale o qui sul mio sito web.

Come connettersi al database

Per connettere il client, cioè il frontend mostrato nel video, al database ho deciso di non utilizzare un pool di connessione diretto verso PostgreSQL. Questa scelta evita di introdurre un ulteriore livello di complessità: utilizzo invece l'SDK mantenuto ufficialmente dal team di sviluppatori di Supabase per JavaScript e TypeScript.

Che cos'è un SDK: un SDK, acronimo di System Development Kit, è una serie di codice già scritto da altri programmatori per permettere ai programmatori di non riscrivere sempre il codice da 0, ma di risparmiare tempo ed energie, evitando di fare errori, riutilizzandone alcune parti nelle loro applicazioni. Viene anche indicato come libreria.

Codice di implementazione

Copia e incolla questo codice nel tuo editor preferito e inserisci le tue credenziali pubbliche per la connessione a Supabase. Ricorda di aggiungere le tabelle come nel video per evitare errori, come colonne non trovate o di tipo dato sbagliato:

<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Supabase CRUD Operations</title>
    <!-- Libreria Supabase JS via CDN -->
    <script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
</head>
<body>
    <h1>Supabase CRUD Example</h1>

    <!-- Operazione CREATE (Insert) -->
    <section>
        <h2>2. Create (Insert)</h2>
        <form id="createForm" onsubmit="createRecord(event)">
            <label for="createTitle">Titolo / Nome:</label>
            <input type="text" id="createTitle" required><br><br>

            <label for="createDesc">Descrizione:</label>
            <input type="text" id="createDesc"><br><br>

            <button type="submit">Inserisci Record</button>
        </form>
    </section>

    <hr>

    <!-- Operazione READ (Select) -->
    <section>
        <h2>3. Read (Select)</h2>
        <button onclick="readRecords()">Carica / Ricarica Tutti i Record</button>
        <h3>Risultati:</h3>
        <pre id="outputRead">Nessun dato caricato</pre>
    </section>

    <hr>

    <!-- Operazione UPDATE -->
    <section>
        <h2>4. Update</h2>
        <form id="updateForm" onsubmit="updateRecord(event)">
            <label for="updateId">ID Record da aggiornare:</label>
            <input type="text" id="updateId" required><br><br>

            <label for="updateTitle">Nuovo Titolo:</label>
            <input type="text" id="updateTitle" required><br><br>

            <label for="updateDesc">Nuova Descrizione:</label>
            <input type="text" id="updateDesc"><br><br>

            <button type="submit">Aggiorna Record</button>
        </form>
    </section>

    <hr>

    <!-- Operazione DELETE -->
    <section>
        <h2>5. Delete</h2>
        <form id="deleteForm" onsubmit="deleteRecord(event)">
            <label for="deleteId">ID Record da eliminare:</label>
            <input type="text" id="deleteId" required><br><br>

            <button type="submit">Elimina Record</button>
        </form>
    </section>

    <script>
        let supabaseClient = null;

        // 1. Inizializzazione Client
        function initSupabase() {
            // INSERISCI QUI I TUOI DATI PRESI DALLA DASHBOARD SUPABASE
            const SUPABASE_URL = 'IL_TUO_SUPABASE_URL';
            const SUPABASE_KEY = 'LA_TUA_CHIAVE_API_SUPABASE_PUBBLICA';

            if (!SUPABASE_URL || !SUPABASE_KEY || SUPABASE_URL.includes('TUO-PROGETTO')) {
                alert('Inserisci sia URL che Anon Key di Supabase nel codice JS!');
                return;
            }

            try {
                supabaseClient = supabase.createClient(SUPABASE_URL, SUPABASE_KEY);
                console.log('Client Supabase inizializzato correttamente.');
            } catch (err) {
                console.error('Errore durante l\'inizializzazione del client:', err);
            }
        }

        function checkClient() {
            if (!supabaseClient) {
                alert('Inizializza prima il client Supabase con URL e Anon Key!');
                return false;
            }
            return true;
        }

        // 2. CREATE (Insert)
        async function createRecord(event) {
            event.preventDefault();
            if (!checkClient()) return;

            const title = document.getElementById('createTitle').value;
            const description = document.getElementById('createDesc').value;

            const { data, error } = await supabaseClient
                .from('products')
                .insert([{ name: title, description: description }])
                .select();

            if (error) {
                console.error('Errore durante la CREATE:', error);
                alert('Errore: ' + error.message);
            } else {
                console.log('CREATE completata con successo:', data);
                document.getElementById('createForm').reset();
                readRecords();
            }
        }

        // 3. READ (Select)
        async function readRecords() {
            if (!checkClient()) return;

            const { data, error } = await supabaseClient
                .from('products')
                .select('*');

            if (error) {
                console.error('Errore durante la READ:', error);
                alert('Errore: ' + error.message);
            } else {
                console.log('READ completata:', data);
                document.getElementById('outputRead').textContent = JSON.stringify(data, null, 2);
            }
        }

        // 4. UPDATE
        async function updateRecord(event) {
            event.preventDefault();
            if (!checkClient()) return;

            const id = document.getElementById('updateId').value;
            const title = document.getElementById('updateTitle').value;
            const description = document.getElementById('updateDesc').value;

            const { data, error } = await supabaseClient
                .from('products')
                .update({ name: title, description: description })
                .eq('id', id)
                .select();

            if (error) {
                console.error('Errore durante l\'UPDATE:', error);
                alert('Errore: ' + error.message);
            } else {
                console.log('UPDATE completata con successo:', data);
                document.getElementById('updateForm').reset();
                readRecords();
            }
        }

        // 5. DELETE
        async function deleteRecord(event) {
            event.preventDefault();
            if (!checkClient()) return;

            const id = document.getElementById('deleteId').value;

            const { data, error } = await supabaseClient
                .from('products')
                .delete()
                .eq('id', id)
                .select();

            if (error) {
                console.error('Errore durante la DELETE:', error);
                alert('Errore: ' + error.message);
            } else {
                console.log('DELETE completata con successo:', data);
                document.getElementById('deleteForm').reset();
                readRecords();
            }
        }

        // Avvio inizializzazione
        initSupabase();
    </script>
</body>
</html>

Una volta fatto ciò puoi eseguire il file in un browser per provarlo e vedere se funziona correttamente.

Se non funziona

Controlla questi punti:

Puoi utilizzare LLM e coding agent per trovare errori. Oppure contattami per richiedere supporto allo sviluppo.