Guida passo-passo alla costruzione di un backend Flutter

Step-by-step guide to build a Flutter backend
Step-by-step guide to build a Flutter backend

In questo articolo si parlerà di Flutter, un kit di sviluppo software open-source per l’interfaccia utente creato da Google.

Esploreremo i vantaggi e gli svantaggi dell’utilizzo di Flutter e metteremo in evidenza le diverse opzioni di backend per la vostra applicazione Flutter.

Infine, imparerete a costruire un backend funzionante per la vostra applicazione Flutter utilizzando la funzione Backend as a Service (BaaS) di Back4apps.

Che cos’è il flutter?

Flutter è un framework di sviluppo multipiattaforma che consente di creare rapidamente applicazioni Android, iOS, Web, Linux, macOS e Windows dall’aspetto nativo.

Con Flutter, molte delle complessità legate alla creazione di applicazioni specifiche per la piattaforma vengono aggirate. Flutter è noto anche per le sue prestazioni veloci e per i bellissimi widget dell’interfaccia utente.

Lo stesso team di Flutter definisce la tecnologia come;

Un framework open-source di Google per la creazione di applicazioni multipiattaforma belle e compilate in modo nativo da un’unica base di codice.

I 3 principali vantaggi e limiti di Flutter

VantaggiLimitazioni
Flutter è un framework veloce con un’ampia gamma di funzionalità pronte all’uso che consentono di accelerare i tempi di sviluppo delle app.Le applicazioni Flutter tendono a essere più grandi di quelle realizzate con altri framework, come React Native.
Le app Flutter sono multipiattaforma e funzionano sia su Android che su iOS, risparmiando tempo e denaro nello sviluppo.Flutter è un framework relativamente nuovo con una comunità relativamente piccola. Questo può rendere difficile trovare aiuto e supporto quando se ne ha bisogno.
Flutter è facile da imparare, anche per i principianti. Con una fantastica documentazione per iniziare.Flutter utilizza il linguaggio di programmazione Dart, che non è così diffuso come altri linguaggi, come Java o JavaScript. Questo potrebbe limitare i pacchetti disponibili.

Quali sono i tipi di backend?

La scelta della giusta opzione di backend per gestire le attività lato server è molto importante quando si costruisce un’applicazione.

Ogni tipo di backend ha i suoi punti di forza e le esigenze specifiche dell’applicazione devono guidare la scelta del backend.

Le seguenti sottosezioni evidenzieranno le diverse opzioni di backend con cui si può lavorare, le loro caratteristiche, il loro funzionamento e il modo in cui possono soddisfare al meglio le esigenze della vostra applicazione.

IaaS

Lo IaaS è un’opzione di backend da prendere in considerazione se si tratta di un’applicazione di grandi dimensioni con molti utenti. IaaS è un modello di cloud computing che sta per Infrastructure as a Service.

Il cloud computing è un modello in cui un fornitore di terze parti fornisce risorse informatiche, come server, storage e applicazioni, attraverso Internet.

È possibile accedere a queste risorse su richiesta, con tariffe a consumo. Con IaaS, il fornitore di cloud mantiene la principale infrastruttura di elaborazione sottostante, mentre voi avrete il controllo completo sulla configurazione dei dati della vostra applicazione, sul sistema operativo e su tutti gli altri requisiti di backend.

Questo lo rende un’ottima opzione di backend per le applicazioni che necessitano di scalare le risorse di calcolo verso l’alto o verso il basso.

PaaS

Platform-as-a-Service (PaaS) e Infrastructure-as-a-Service (IaaS) sono due modelli distinti di cloud computing che servono a scopi diversi. Sebbene entrambi offrano flessibilità e scalabilità, rispondono a esigenze diverse nello sviluppo e nella distribuzione delle applicazioni.

Un backend PaaS vi fornirà un ambiente di sviluppo completo, astraendo dalle complessità della gestione dei server, delle reti e dello storage. Il PaaS è più adatto se volete concentrarvi sulla creazione e sulla manutenzione delle applicazioni senza preoccuparvi della gestione dell’infrastruttura.

BaaS

Un backend BaaS (Backend-as-a-Service) fornisce servizi e funzionalità di backend pronti all’uso, consentendo di concentrarsi sulla costruzione e sul miglioramento dell’esperienza utente dell’applicazione senza gestire l’infrastruttura di backend.

Con BaaS, gli sviluppatori possono accedere a funzionalità come l’autenticazione degli utenti, i database e lo storage attraverso le API, eliminando la necessità di configurare e mantenere i server di backend.

È come utilizzare un pezzo di puzzle già pronto che si adatta perfettamente alla vostra applicazione, risparmiando tempo e fatica.

In sostanza, il BaaS semplifica il processo di sviluppo, consentendo agli sviluppatori di concentrarsi sugli aspetti delle loro applicazioni rivolti all’utente e di affidarsi a servizi backend precostituiti per gestire il lavoro pesante.

Come costruire un backend Flutter usando un backend come servizio

Questa sezione illustra come iniziare a costruire il backend di un’applicazione Flutter. La piattaforma Back4app è un’ottima opzione per costruire applicazioni backend scalabili e sicure, flessibili e facili da distribuire.

Panoramica di Back4app

Back4App è una piattaforma Backend-as-a-Service (BaaS) che semplifica lo sviluppo di applicazioni mobili e web fornendo un’infrastruttura backend completa.

Utilizzando Back4App, potrete concentrarvi sulla realizzazione delle funzionalità front-end della vostra applicazione.

La piattaforma offre un’ampia gamma di servizi backend pronti all’uso, tra cui database, API e funzioni cloud.

Le caratteristiche e i vantaggi principali di Back4app includono:

  • Database relazionali e non relazionali
  • API REST e GraphQL
  • Quesiti in diretta
  • Ampia gamma di opzioni di autenticazione
  • Hosting scalabile
  • Notifiche push e via e-mail

Back4App utilizza il server Parse, un kit open-source per lo sviluppo di componenti lato server di un’applicazione. Con supporto per diverse tecnologie. Questa guida di riferimento elenca le diverse tecnologie supportate da Back4app.

Introduzione al progetto

Lo scopo di questa guida è costruire un backend Back4app per supportare un’applicazione Flutter. L’applicazione si connetterà e interagirà con il backend impostato utilizzando l’SDK del server Parse.

L’applicazione che realizzerete è una semplice applicazione di contatti che consente agli utenti di creare e leggere i contatti. Questi contatti saranno memorizzati utilizzando il supporto per il database PostgreSQL di Back4app.

Gli utenti possono aggiungere nuovi contatti inserendo le informazioni del contatto nell’app.

Alla fine di questa guida, avrete una solida conoscenza di come:

  • Costruire un’applicazione backend sulla piattaforma Back4app
  • Scrivere su un database strutturato Back4app
  • Gestire le basi della sicurezza del backend di Parse.

Prerequisiti

Per seguire questa guida, è necessario soddisfare i seguenti prerequisiti:

  • Familiarità con il linguaggio Dart e il framework Flutter
  • Conoscenza della manipolazione dello stato in Flutter
  • Un simulatore o emulatore di dispositivi per eseguire la vostra applicazione. Xcode per iOS o Android Studio per Android.
  • Conoscenza di base dei database relazionali e non relazionali

Creare un’applicazione

Per creare il backend è necessario disporre di un account Back4app. Se non ne avete uno, potete crearlo seguendo la procedura di registrazione per unaccount gratuito .

Se avete già un account con Back4app,accedete e create una nuova applicazione. Selezionare Backend as a Service come opzione di servizio.

I tipi di opzioni di back4app create new app

In questo modo si creerà un backend BaaS scalabile. Non dimenticate di dare un nome unico alla vostra applicazione. Per quanto riguarda il database, Back4app offre PostgreSQL come opzione.

PostgreSQL è un popolare sistema di gestione di database relazionali (RDBMS) open-source. È noto per la sua scalabilità, affidabilità, alte prestazioni e sicurezza.

L’utilizzo dell’opzione beta PostgreSQL in Back4app consente di sfruttare queste caratteristiche e questi vantaggi.

Creare una nuova applicazione con il nome dell'applicazione e l'opzione database SQL

La fase di compilazione dovrebbe svolgersi rapidamente. Al termine, si accederà alla dashboard dell’applicazione.

Database PostgreSQL

In Back4App è possibile definire classi e campi che rappresentano i dati dell’applicazione. PostgreSQL utilizza database relazionali, un metodo strutturato di archiviazione dei dati per gli utenti dell’applicazione.

Come accennato in precedenza, la nostra applicazione Flutter sarà una rubrica di contatti in cui potremo memorizzare più contatti. I database PostgreSQL contengono relazioni. Un modello di dati ragionevole per questa applicazione sarebbe una classe contatti e la città ZipCode del contatto.

Cominciamo con il modello Contatti. La tabella dei contatti richiede i diversi campi;

  • ContattoId/OggettoId
  • Nome
  • Numero di telefono
  • Codice postale

La tabella del modello di dati sarà simile a questa;

Contatto

CampoTipo di datiVincoli
contattoIdINTEGROCHIAVE PRIMARIA
nomeSTRINGANON NULLO
numero di telefonoINTEGRONON NULLO
codice postalePUNTONON NULLO

Codice postale

CampoTipo di datiVincoli
OggettoIdINTEGROCHIAVE PRIMARIA
codice postaleINTEGRONON NULLO

L’oggetto Contact memorizza le informazioni del contatto, con il contactId come chiave primaria. I campi name, phoneNumber e zipCode devono essere compilati obbligatoriamente (NOT NULL),

Questo modello di dati crea una relazione tra le tabelle dell’applicazione Contatti, consentendo di gestire le informazioni sui contatti e di associare più campi a ciascun contatto.

Per creare queste due classi nell’applicazione Back4app, premere il pulsante Crea una classe nell’angolo in alto a sinistra della dashboard.

Creare un pulsante di classe nella dashboard dell'applicazione

Nominare la classe Contatto e attivare l’opzione “è un campo obbligatorio?”.

a creare e aggiungere una nuova colonna modale

Creare le colonne per i campi dati di Contact e poi fare lo stesso per la classe ZipCode. Back4app consente di personalizzare ogni colonna creata.

Pannello di amministrazione

Back4App fornisce un’intuitiva interfaccia grafica (GUI), chiamata Admin Panel, per gestire il backend delle vostre applicazioni senza alcuno sforzo.

Il pannello di amministrazione è un potente strumento per monitorare, modificare e analizzare i dati, che lo rende una risorsa preziosa per la gestione delle app.

È possibile accedere al pannello di amministrazione dell’applicazione all’interno della stessa. Nella dashboard dell’app, sotto la voce “Altro”si trova un pulsante o un link con la dicitura“Pannello di amministrazione“, che indirizza al pannello di amministrazione. Da qui è possibile attivare e abilitare l’app di amministrazione.

Verranno forniti un nome utente e una password per accedere all’app di amministrazione.

L’ultimo passo per configurare l’app di amministrazione è scegliere un nome di dominio da utilizzare per accedere al pannello.

Per questa guida, un buon esempio potrebbe essere: flutter-backend.admin.back4app.com.

Ora è possibile accedere alla dashboard di amministrazione aprendo il dominio fornito in un browser.

Per saperne di più su Back4app Admin App, visitate i documenti ufficiali.

Protezione dell’app

Attualmente, l’applicazione di backend è completamente vulnerabile e le informazioni al suo interno possono essere manomesse dal lato client.

Per evitare che ciò accada in fase di produzione, è possibile configurare le norme e le autorizzazioni di accesso.

Per controllare il modo in cui le classi vengono create e disabilitare la creazione di classi dal lato client, andare in Dashboard > Impostazioni dell’app e individuare Creazione di classi client. Disattivare questa opzione, in quanto l’applicazione attualmente richiede solo le due classi create.

Quando si disattiva, viene visualizzata una finestra a comparsa. Questo serve a confermare e salvare le modifiche apportate all’applicazione.

un interruttore a levetta per l'autenticazione della creazione della classe client

Test API CRUD con Flutter

In questa sezione, testerete le funzioni API di backend e il database della vostra applicazione con un’applicazione Flutter che costruirete. Inizierete con la costruzione dell’interfaccia utente dell’applicazione Flutter.

Per inizializzare un’applicazione Flutter è necessario installare l’SDK Flutter sul computer.

Seguite i documenti ufficiali di Flutter per installare l’SDK Flutter e gli strumenti necessari per creare un’applicazione Flutter sul vostro computer Windows o Mac.

Per inizializzare un’applicazione Flutter, eseguite i seguenti comandi nel vostro terminale:

#Initialize your Flutter app
flutter create my_flutter_app

#Run your Flutter app
flutter run

Questi comandi creano un’impalcatura e avviano una semplice applicazione Flutter su cui costruire.

Per mantenere questa guida semplice, il file main.dart conterrà la maggior parte del codice per eseguire l’applicazione Flutter. Non discuteremo del codice di Flutter in questa sede, poiché non è lo scopo della guida.

Sovrascrivete tutto il codice in main.dart con il seguente:

import 'dart:ffi';

import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final keyApplicationId = 'appID';
  final keyClientKey = 'clientKey';
  final keyParseServerUrl = '<https://parseapi.back4app.com>';

  await Parse().initialize(keyApplicationId, keyParseServerUrl,
      clientKey: keyClientKey, debug: true);

  runApp(MaterialApp(
    title: 'Contacts',
    theme: ThemeData(
      primaryColor: Colors.white,
    ),
    home: ContactsApp(),
  ));
}

class ContactsApp extends StatefulWidget {
  const ContactsApp({Key? key}) : super(key: key);

  @override
  // ignore: library_private_types_in_public_api
  _ContactsAppState createState() => _ContactsAppState();
}

class _ContactsAppState extends State<ContactsApp> {
  List<Contact> contacts = [];
  String? selectedZipCode; // Initialize with a default value

  @override
  void initState() {
    super.initState();
    selectedZipCode = '1234'; // Initialize with a default value
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Contacts'),
      ),
      body: ListView.builder(
        itemCount: contacts.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(contacts[index].name),
            subtitle: Text(contacts[index].phoneNumber),
            trailing: IconButton(
              icon: const Icon(Icons.delete),
              onPressed: () {
                setState(() {
                  contacts.removeAt(index);
                });
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _showAddContactDialog();
        },
        child: const Icon(Icons.add),
      ),
    );
  }

  void _showAddContactDialog() async {
    showDialog(
      context: context,
      builder: (context) {
        String name = '';
        String phoneNumber = '';

        return AlertDialog(
          title: const Text('Add Contact'),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                decoration: const InputDecoration(labelText: 'Name'),
                onChanged: (value) {
                  name = value;
                },
              ),
              TextField(
                decoration: const InputDecoration(labelText: 'Phone Number'),
                onChanged: (value) {
                  phoneNumber = value;
                },
              ),
              // Checkbox for Zip Code
              ListTile(
                title: const Text('Select Zip Code'),
                subtitle: Column(
                  children: [
                    RadioListTile(
                      title: const Text('1234'),
                      value: '1234',
                      groupValue: selectedZipCode,
                      onChanged: (value) {
                        setState(() {
                          selectedZipCode = value;
                        });
                        print(selectedZipCode);
                      },
                    ),
                    RadioListTile(
                      title: const Text('4321'),
                      value: '4321',
                      groupValue: selectedZipCode,
                      onChanged: (value) {
                        setState(() {
                          selectedZipCode = value;
                        });
                        print(selectedZipCode);
                      },
                    ),
                  ],
                ),
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text('Cancel'),
            ),
            ElevatedButton(
              onPressed: () async {
                setState(() {
                  contacts.add(Contact(
                    name: name,
                    phoneNumber: phoneNumber,
                    zipCode: selectedZipCode as String,
                  ));
                });

                // Save the contact to Back4App
                final contact = ParseObject('Contact');
                contact.set('name', name);
                contact.set('phoneNumber', phoneNumber);
                contact.set(
                    'zipCode',
                    (ParseObject('ZipCode')..objectId = selectedZipCode.objectId)
                        .toPointer());

                await contact.save();

                // ignore: use_build_context_synchronously
                Navigator.of(context).pop();
              },
              child: const Text('Save'),
            ),
          ],
        );
      },
    );
  }
}

class Contact {
  final String name;
  final String phoneNumber;
  final String zipCode;

  Contact({
    required this.name,
    required this.phoneNumber,
    required this.zipCode,
  });
}

class ZipCode {
  final String zipCode;

  ZipCode({
    required this.zipCode,
  });
}

In questo modo, avrete l’interfaccia utente di base per la vostra applicazione Flutter.

Ora è possibile avviare l’implementazione di Back4app. Back4app utilizza il Parse Flutter SDK per integrare Parse Server in un’applicazione Flutter.

Parse Server è una piattaforma di backend open-source che fornisce un’infrastruttura pronta all’uso per la gestione dei dati delle app.

Con l’SDK, è possibile comunicare con l’API di Parse Server dalla propria applicazione Flutter, rendendo più semplice l’esecuzione di operazioni CRUD (Create, Read, Update, Delete) sui dati, la gestione delle sessioni utente e altre funzionalità lato server.

Per utilizzare l’SDK Parse, installarlo come dipendenza nel file pubspec.yaml del progetto Flutter.

Specificare il server Parse:

dependencies:
	# Parse SDK
  parse_server_sdk_flutter: ^5.1.1

  flutter:
    sdk: flutter

Assicurarsi che l’indentazione sia accurata. I file .yaml sono molto sensibili alle maiuscole e alle indentazioni.

Eseguire il comando per installare la dipendenza specificata:

flutter pub get

Andare in main.dart e importare l’SDK Parse aggiunto:

import 'package:parse_server_sdk_flutter/parse_server_sdk_flutter.dart';

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
	// code for runApp()

  const keyApplicationId = 'YOUR_APPLICATION_ID_HERE';
  const keyClientKey = 'YOUR_CLIENT_KEY_HERE';
  const keyParseServerUrl = '<https://parseapi.back4app.com>';

  await Parse().initialize(keyApplicationId, keyParseServerUrl,
      clientKey: keyClientKey, debug: true);
}

Qui si importa il ParseSDk nel file main.dart. Si inizializza anche Parse all’interno di main(), chiamando Parse().initialize(). Poiché si tratta di un programma asincrono, contrassegnare main() con la parola chiave async.

I segnaposto per Application_Id e Client Key devono essere sostituiti con i valori reali. Queste sono le credenziali dell’applicazione per comunicare con il backend.

Per ottenere queste chiavi, andare su Impostazioni app > Sicurezza e chiavi dalla dashboard di Back4app. Quindi sostituire i segnaposto con le rispettive chiavi.

All’avvio dell’applicazione, viene lanciato main(), Parse viene inizializzato con l’applicazione e l’applicazione Flutter viene collegata al backend Back4app.

Scrittura nella classe Contact e ZipCode

Qui si apprende come creare e scrivere sulle classi del database dal lato client dell’applicazione. Per creare le classi Contact e Birthday, si modificherà main.dart.

All’interno del metodo onPressed() del widget del pulsante elevato, si utilizzerà ParseObject() per creare una nuova istanza della classe Contatti :

final contact = ParseObject('Contact');
contact.set('name', name);
contact.set('phoneNumber', phoneNumber);

final ParseResponse parseResponse = await contact.save();

if (parseResponse.success) {
   final contactId = (parseResponse.results!.first as ParseObject).objectId!;
		print('Object created: $contactId');

	} else {
      print('Object created with failed: ${parseResponse.error.toString()}');
    }

L’SDK Parse Flutter utilizza ParseObject() per creare una nuova istanza di qualsiasi nome di classe passato come argomento. Chiamando Contact.set() con il nome del campo dell’oggetto e i suoi valori, questi campi verranno scritti e aggiornati.

È possibile creare un oggetto ParseResponse per contenere i risultati dell’operazione di salvataggio. ParseResponse conterrà una proprietà success, che sarà true se l’operazione di salvataggio ha avuto successo e false se l’operazione di salvataggio è fallita.

Il codice inizializza quindi una variabile contactId a null. Questa variabile sarà utilizzata per memorizzare l’objectId generato automaticamente dell’oggetto contatto salvato. Segue poi la gestione degli errori.

Sotto il codice sopra riportato:

final zipCodeObject = ParseObject('ZipCode')
    ..objectId = selectedZipCode as String;
zipCodeObject.set('zipCode', selectedZipCode);
contact.set('zipCode', zipCodeObject.toPointer());

await contact.save();
await zipCodeObject.save();

Qui si crea il ParseObject del codice postale. Quando si aggiunge un nuovo contatto attraverso la finestra di dialogo, il codice creerà correttamente un oggetto ZipCode e lo assocerà al campo ZipCode dell’oggetto Contact.

Utilizza l’objectId del codice postale selezionato per stabilire l’associazione come puntatore. Utilizzare il metodo .save() per salvare entrambi gli oggetti nel backend.

Interrogazione/lettura dei dati dal database

Qui discuteremo come inviare una query al database dalla vostra applicazione Flutter. È possibile effettuare una query per recuperare tutti i contatti con lo stesso codice postale. Questo sarebbe piuttosto complesso da realizzare in un sistema di database non relazionale.

Se il recupero è riuscito, è possibile visualizzare un elenco di tutti i contatti nell’app Flutter.

Per recuperare un elenco di contatti con lo stesso codice postale:

Future<void> _loadContacts() async {
  final queryBuilder = QueryBuilder<ParseObject>(ParseObject('Contact'))
    ..whereEqualTo('zipCode', selectedZipCode) // Filter by zip code
    ..orderByAscending('name');

  final response = await queryBuilder.query();

  if (response.success && response.results != null) {
    final List<Contact> loadedContacts = response.results!.map((parseObject) {
      return Contact(
        name: parseObject.get('name'),
        phoneNumber: parseObject.get('phoneNumber'),
        zipCode: parseObject.get('zipCode')!.objectId,
      );
    }).toList();

    setState(() {
      //set your contacts to loadedContacts
    });
  }
}

@override
  void initState() {
    super.initState();
   
    _loadContacts(); // Load contacts when the app starts
  }

Il metodo _loadContacts crea una query alla classe Contacts, alla ricerca di oggetti di contatto con il codice postale specificato.

Il metodo restituisce quindi i contatti in un elenco ordinandoli per nome in ordine crescente in base al campo “nome”.

All’avvio dell’applicazione(initState), il metodo _loadContacts viene richiamato per recuperare i contatti con il codice postale selezionato.

Conclusione

Avere un backend controllato dove poter strutturare correttamente il flusso di dati nella vostra applicazione è assolutamente necessario. Con Back4app, potete creare il backend della vostra applicazione mobile in movimento.

È inoltre possibile utilizzare la piattaforma Back4app per implementare l’autenticazione degli utenti con un database del modello utente impostato.

Che cos’è Flutter?

Flutter è un framework di sviluppo che consente di creare app simili a quelle native su più piattaforme. Semplifica il processo di creazione di app specifiche per piattaforma ed è noto per la sua velocità di sviluppo e per le interfacce utente accattivanti.

Quali sono le opzioni di deployment per il backend?

IaaS
PaaS
– BaaS

Come creare un backend per un’app Flutter?

1. Pianifica la struttura del modello di dati del tuo app
2. Configura un database che rifletta tale struttura
3. Scrivi la logica dell’interfaccia utente e collegala al backend
4. Testa il backend per eventuali vulnerabilità di sicurezza ed esegui operazioni CRUD
5. Scegli una piattaforma di deployment come Back4app
6. Esegui il deployment della tua app sul backend


Leave a reply

Your email address will not be published.