# Guida: Come Creare un Plugin Grafana con Frontend e Backend ## Introduzione Questa guida spiega come creare un plugin Grafana completo che include sia frontend (React/TypeScript) che backend (Go), con funzionalità per salvare e recuperare testi tramite API. ## Cosa abbiamo creato Un'applicazione Grafana che permette di: - Inserire un messaggio di testo tramite un form - Salvare il messaggio nel backend (in un file) - Caricare e visualizzare il messaggio salvato come messaggio di benvenuto - Gestire stati di caricamento ed errori ## Passaggi Realizzati ### 1. Creazione del Plugin Base ```bash # Navigazione nella directory di lavoro cd /home/enne2/Sviluppo/grafana-plugin # Creazione del plugin usando lo strumento ufficiale npx @grafana/create-plugin@latest ``` **Configurazione selezionata:** - Tipo di plugin: **app** (applicazione) - Backend: **Sì** (per supportare funzionalità server-side) - Nome plugin: **fullstack-test** - Organizzazione: **enne2 corp** Il comando ha generato automaticamente: - Struttura completa del progetto - File di configurazione (package.json, tsconfig.json, docker-compose.yaml) - Template per frontend e backend - Test end-to-end con Playwright - GitHub Actions per CI/CD ### 2. Installazione delle Dipendenze ```bash cd enne2corp-fullstacktest-app npm install ``` ### 3. Implementazione del Frontend #### Modifica di PageOne.tsx Ho modificato il file `src/pages/PageOne.tsx` per aggiungere: **Import necessari:** ```typescript import React, { useState, useEffect } from 'react'; import { Input, Button, Alert } from '@grafana/ui'; import { getBackendSrv } from '@grafana/runtime'; ``` **Stato del componente:** ```typescript const [textValue, setTextValue] = useState(''); const [savedValue, setSavedValue] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [success, setSuccess] = useState(''); ``` **Funzioni principali:** - `loadSavedValue()`: Carica il messaggio salvato dal backend - `handleSaveText()`: Invia il nuovo messaggio al backend **UI implementata:** - Messaggio di benvenuto (se presente un valore salvato) - Form con input di testo e pulsante - Gestione di stati di caricamento, errori e successo - Styling personalizzato usando Emotion CSS ### 4. Implementazione del Backend #### Modifica di resources.go Ho aggiunto due nuovi endpoint nel file `pkg/plugin/resources.go`: **1. Endpoint per salvare testo (`/save-text`):** ```go func (a *App) handleSaveText(w http.ResponseWriter, req *http.Request) { // Validazione metodo POST // Decodifica JSON del messaggio // Creazione directory di dati se necessaria // Salvataggio in file /tmp/grafana-plugin-data/saved_message.txt // Risposta JSON di conferma } ``` **2. Endpoint per recuperare testo (`/get-text`):** ```go func (a *App) handleGetText(w http.ResponseWriter, req *http.Request) { // Validazione metodo GET // Controllo esistenza file // Lettura contenuto file // Risposta JSON con il messaggio } ``` **Registrazione dei nuovi endpoint:** ```go func (a *App) registerRoutes(mux *http.ServeMux) { mux.HandleFunc("/ping", a.handlePing) mux.HandleFunc("/echo", a.handleEcho) mux.HandleFunc("/save-text", a.handleSaveText) // NUOVO mux.HandleFunc("/get-text", a.handleGetText) // NUOVO } ``` #### Correzione di app.go Ho dovuto correggere la funzione `NewApp` per rimuovere il parametro `context.Context` che causava un errore di compilazione: ```go // PRIMA (errato) func NewApp(ctx context.Context, settings backend.AppInstanceSettings) (instancemgmt.Instance, error) // DOPO (corretto) func NewApp(settings backend.AppInstanceSettings) (instancemgmt.Instance, error) ``` ### 5. Installazione di Go e Mage ```bash # Installazione di Go sudo apt update && sudo apt install -y golang-go # Installazione di Mage (build tool) go install github.com/magefile/mage@latest # Aggiunta al PATH export PATH=$PATH:$(go env GOPATH)/bin ``` ### 6. Build del Backend ```bash mage -v build:linux ``` Questo comando ha compilato il codice Go e creato l'eseguibile `dist/gpx_fullstack_test_linux_amd64`. ## Struttura File Principali ``` enne2corp-fullstacktest-app/ ├── src/ │ ├── pages/ │ │ └── PageOne.tsx # Frontend con form e logica │ └── components/ ├── pkg/ │ ├── main.go # Entry point del backend │ └── plugin/ │ ├── app.go # Configurazione app │ └── resources.go # API endpoints ├── package.json # Dipendenze frontend ├── go.mod # Dipendenze backend ├── docker-compose.yaml # Ambiente di sviluppo └── Magefile.go # Build configuration ``` ## Funzionalità Implementate ### Frontend (React/TypeScript) - **Form di input**: Campo testo + pulsante per inserire messaggi - **Caricamento automatico**: All'avvio carica il messaggio salvato - **Messaggio di benvenuto**: Mostra il testo salvato in evidenza - **Gestione stati**: Loading, errori, successo con feedback visuale - **Styling**: Design coerente con il tema Grafana ### Backend (Go) - **API REST**: Due endpoint `/save-text` e `/get-text` - **Persistenza**: Salvataggio in file system (`/tmp/grafana-plugin-data/`) - **Validazione**: Controllo input e gestione errori - **JSON**: Comunicazione via JSON tra frontend e backend ### Comunicazione Frontend-Backend - **Salvataggio**: `POST /api/plugins/enne2corp-fullstacktest-app/resources/save-text` - **Recupero**: `GET /api/plugins/enne2corp-fullstacktest-app/resources/get-text` - **Grafana Backend Service**: Uso di `getBackendSrv()` per le chiamate API ## Prossimi Passi per Completare Per testare l'applicazione completa: 1. **Build del frontend:** ```bash npm run dev ``` 2. **Avvio ambiente di sviluppo:** ```bash npm run server ``` 3. **Apertura di Grafana:** - URL: http://localhost:3000 - Navigare al plugin per testare le funzionalità ## Note Tecniche - **Persistenza**: I dati sono salvati in `/tmp/grafana-plugin-data/saved_message.txt` - **CORS**: Gestito automaticamente dal framework Grafana - **Autenticazione**: Gestita dal sistema Grafana - **Errori**: Logging sia frontend che backend per debugging Questa implementazione fornisce una base solida per plugin Grafana più complessi che richiedono comunicazione bidirezionale tra frontend e backend.