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:
- Verifica che
SUPABASE_URLe la chiave pubblica siano corrette. - Controlla che la tabella
productsesista e abbia le colonnenameedescription. - Se visualizzi
Failed to fetch, verifica la connessione internet e l'URL del progetto Supabase. - Controlla le policy RLS: disattivate in questo tutorial per scopi didattici, non disattivare mai le RLS in ambienti di produzione se previste nell'architettura.
- Apri il file tramite un server locale o direttamente nel browser.
Puoi utilizzare LLM e coding agent per trovare errori. Oppure contattami per richiedere supporto allo sviluppo.