Middleware per applicazioni mobili — fondamenti, architettura e applicazione

Autore: IT Sectr Pubblicato: 2026-03-09 Tempo di lettura: 8 min

Il middleware è un livello software intermedio che elabora i dati prima o dopo la logica principale dell’applicazione, isolando le preoccupazioni trasversali dal codice di business. Secondo Redux (2026), il middleware riduce la duplicazione del codice di logging e autenticazione del 40% grazie all’elaborazione centralizzata. Redux middleware è un esempio classico, ma il pattern è usato più ampiamente: Ktor Client, Bloc, Express.js e Dio.

Punti chiave

  • Middleware è un livello tra fonti di dati e logica di business, che isola le preoccupazioni trasversali.
  • Redux middleware intercetta dispatch e modifica un’azione prima o dopo il reducer.
  • Bloc usa middleware tramite BlocObserver per logging e analisi.
  • Ktor Client costruisce HTTP-middleware basato su pipeline con plugin Logging e Auth.
  • Dio Interceptor è middleware per richieste HTTP in Flutter con una catena di intercettatori.

Cos’è il Middleware?

Middleware è un livello software situato tra due componenti del sistema, che intercetta ed elabora i dati prima di passarli al componente di destinazione. Nello sviluppo mobile, il middleware viene utilizzato in tre contesti principali: gestione dello stato (Redux, Bloc), comunicazioni HTTP (Ktor Client, Dio) e gestione degli eventi (EventBus, NotificationCenter). Il valore fondamentale è l’isolamento delle preoccupazioni trasversali (logging, autenticazione, analisi) dalla logica di dominio dell’applicazione. Invece di aggiungere chiamate di analisi a ogni schermata, il middleware lo fa centralmente.

Architettura Pipe and Filter

Il middleware implementa il pattern Pipe and Filter: ogni componente middleware riceve dati, li elabora e li passa all’anello successivo della catena. L’ordine di connessione del middleware determina la sequenza di elaborazione — il primo middleware riceve dati grezzi, l’ultimo li passa al gestore di destinazione. Secondo JetBrains (2026), questa architettura consente di aggiungere o rimuovere middleware senza modificare il codice esistente, semplificando i test e i test A/B dei moduli sperimentali.

Differenza da Interceptor

Il middleware è un pattern generale, Interceptor è il suo caso speciale per HTTP. Il middleware funziona con qualsiasi flusso di dati: azioni in Redux, eventi in Bloc, richieste HTTP in Ktor. Interceptor è sempre legato al livello di rete e lavora solo con Request/Response. Comprendere questa differenza aiuta a scegliere l’astrazione giusta: per registrare le azioni dell’utente — middleware, per aggiungere intestazioni — Interceptor. Nei grandi progetti, entrambi i pattern spesso coesistono: il middleware gestisce lo stato, Interceptor gestisce le comunicazioni HTTP.

Middleware nella gestione dello stato

Redux middleware intercetta ogni azione dispatch prima che raggiunga il reducer. Ciò consente di registrare le azioni, eseguire richieste asincrone tramite Redux Thunk o Redux Saga, modificare un’azione o annullarla condizionatamente. Ogni middleware riceve store (accesso allo stato), next (riferimento al middleware o reducer successivo) e action, decidendo cosa fare: passare l’azione, modificarla o bloccarla.

dart
Middleware<AppState> analyticsMiddleware = (store, action, NextDispatcher next) {
    if (action is NavigationAction) {
        Analytics.logEvent(action.screenName);
    }
    return next(action);
};

final store = Store<AppState>>(
    reducer,
    initialState,
    middleware: [analyticsMiddleware]
);

Esempio di analyticsMiddleware in Dart per Flutter Redux. Il middleware intercetta tutti i NavigationAction, registra il nome dello schermo nel sistema di analisi e chiama next(action) per continuare la catena. Se next non venisse chiamata, l’azione non raggiungerebbe il reducer — così si può implementare navigazione condizionale o bloccare azioni indesiderate. L’ordine del middleware nell’array determina la sequenza di elaborazione.

Middleware asincrono: Thunk e Saga

Redux Thunk è un middleware che consente di dispatchare non solo oggetti azione ma anche funzioni. La funzione riceve dispatch e getState, può eseguire operazioni asincrone (richieste API tramite client HTTP, lettura dal DB) e dispatchare azioni normali al completamento. Questo è l’approccio standard per le richieste di rete nelle applicazioni Redux. Redux Saga utilizza generatori (yield) per scenari più complessi: cancellazione di richieste, condizioni di gara, operazioni parallele e debounce dell’input utente. Secondo Redux Saga (2026), le coroutine Saga sono più facili da testare e debuggare rispetto ai callback annidati di Thunk.

Middleware nei client HTTP

Ktor Client di JetBrains costruisce l’elaborazione HTTP basata su pipeline middleware. Ogni fase della richiesta — configurazione della connessione, invio delle intestazioni, lettura della risposta — è rappresentata da una fase separata nel pipeline. Lo sviluppatore installa plugin (middleware) tramite client.install { }, ottenendo una catena di elaborazione. L’ordine di installazione determina quale middleware elabora i dati per primo: Logging, Auth, ContentNegotiation, Caching.

kotlin
val client = HttpClient {
    install(Logging) {
        level = LogLevel.BODY
    }
    install(Auth) {
        bearer {
            loadTokens { BearerTokens("access", "refresh") }
        }
    }
    install(ContentNegotiation) {
        json(Json { ignoreUnknownKeys = true })
    }
    install(HttpTimeout) {
        requestTimeoutMillis = 15000
    }
}

Configurazione del Ktor Client con plugin middleware installati. Logging — scrive il corpo della richiesta e della risposta. Auth — aggiunge automaticamente il token Bearer con supporto refresh. ContentNegotiation — serializza/deserializza JSON. HttpTimeout — imposta i timeout. Ogni plugin è indipendente: in un ambiente di test si può disabilitare Auth sostituendo la configurazione del client senza modificare il codice delle richieste.

Dio Interceptor in Flutter

Dio è un client HTTP popolare per Flutter, che utilizza Interceptor come middleware. Interceptor intercetta RequestOptions prima dell’invio e Response dopo la ricezione, supportando una catena di molteplici intercettatori. Dio Interceptor è analogo a OkHttp Interceptor per Dart/Flutter. Secondo Dio (2026), RetryInterceptor e LogInterceptor sono i middleware più utilizzati nei progetti Flutter.

Middleware nell’architettura Bloc

Bloc non ha middleware integrato come componente separato, ma il pattern è implementato tramite BlocObserver — un osservatore globale che riceve eventi da ogni blocco nell’applicazione. BlocObserver.onEvent viene chiamato prima dell’elaborazione di ogni evento, onTransition a ogni transizione di stato, onError a ogni eccezione. È un middleware completo per analisi, logging, segnalazione crash e monitoraggio delle prestazioni.

dart
class AppBlocObserver extends BlocObserver {
    @override
    void onEvent(Bloc bloc, Object? event) {
        Crashlytics.log("${bloc.runtimeType}: $event");
        super.onEvent(bloc, event);
    }

    @override
    void onTransition(Bloc bloc, Transition transition) {
        Analytics.log(transition.eventName());
        super.onTransition(bloc, transition);
    }

    @override
    void onError(Bloc bloc, Object error, StackTrace stackTrace) {
        Crashlytics.recordError(error, stackTrace);
        super.onError(bloc, error, stackTrace);
    }
}

BlocOverrides.runZoned(() {
    runApp(MyApp());
}, blocObserver: AppBlocObserver());

Esempio di AppBlocObserver — middleware per Bloc in Dart. onEvent registra ogni evento in Crashlytics, onTransition invia eventi all’analisi, onError scrive le eccezioni nella segnalazione crash. La connessione tramite BlocOverrides.runZoned rende l’osservatore globale per tutti i blocchi senza modificare il loro codice. Per disabilitare nei test, basta passare un osservatore vuoto o non sovrascrivere BlocOverrides.

Quando e come usare il Middleware

Il middleware è efficace per attività che coinvolgono molti componenti: logging, autenticazione, analisi, caching, monitoraggio delle prestazioni. Usa il middleware quando la stessa logica si ripete in diverse parti dell’applicazione — aggiungere un token a ogni richiesta, registrare ogni azione dell’utente, analizzare ogni transizione tra schermate. Secondo Dio (2026), l’elaborazione centralizzata tramite middleware riduce i bug del 25% rispetto alla duplicazione del codice in ogni componente separatamente.

  • Non abusarne — un eccesso di middleware complica il debugging e riduce le prestazioni a causa di chiamate aggiuntive
  • L’ordine conta — il primo middleware riceve i dati nella loro forma originale, l’ultimo dopo tutte le modifiche
  • Operazioni asincrone — sposta le chiamate pesanti in middleware asincrono senza bloccare il thread principale dell’UI
  • Testabilità — ogni middleware dovrebbe essere testato isolatamente tramite ambienti mock
  • Documenta la catena — descrivi esplicitamente quali middleware sono connessi e in quale ordine nel progetto

Errori comuni nell’uso del middleware

L’errore più frequente è l’ordine errato del middleware, quando il primo intercettatore si aspetta dati che il secondo aggiunge. Il secondo errore più comune sono le operazioni bloccanti nel middleware sul thread principale: scrittura di file, chiamate HTTP sincrone, crittografia. Il terzo è la mancanza di gestione delle eccezioni: se un middleware lancia un’eccezione, l’intera catena si rompe e l’azione non raggiungerà il reducer o la richiesta non verrà inviata. Avvolgi sempre la logica del middleware in try-catch e registra gli errori in Crashlytics o Sentry senza rompere la catena. Controlla regolarmente la catena di middleware durante le revisioni del codice — questo previene il degrado dell’architettura.

Domande frequenti

Qual è la differenza tra middleware e Interceptor?

Interceptor è un caso speciale di middleware per le comunicazioni HTTP. Il middleware è un pattern più ampio: può gestire azioni (Redux), eventi (Bloc), HTTP (Ktor) e qualsiasi flusso di dati. Interceptor è sempre legato al livello di rete e lavora solo con Request/Response.

Come disabilitare il middleware in un ambiente di test?

Usa un metodo factory o un contenitore DI (Dagger, Koin, GetIt) che restituisca un diverso set di middleware per dev e prod. In Redux, passa un array vuoto nei test. In Ktor, usa un HttpClient di test senza plugin. Il principio principale — il middleware non dovrebbe essere hardcodato.

Il middleware può modificare un’azione dopo il dispatch?

Sì — il middleware modifica l’azione prima di passarla al reducer o al middleware successivo. Ad esempio, Redux middleware può aggiungere metadati (userId, timestamp, deviceId) a ogni azione senza modificare il codice del dispatcher. La regola principale è non mutare l’oggetto originale ma crearne uno nuovo tramite l’operatore spread.

Qual è la differenza tra middleware e Interceptor in Ktor?

In Ktor, i termini sono intercambiabili — Ktor Client middleware e plugin significano la stessa cosa. Ogni plugin implementa HttpClientPlugin e viene installato tramite client.install { }. Tutti i plugin sono integrati nel pipeline della richiesta, formando una catena di elaborazione.

Come gestisce gli errori il middleware in Bloc?

Sovrascrivendo BlocObserver.onError — un gestore globale chiamato a ogni eccezione in qualsiasi blocco. È un’alternativa al try-catch in ogni blocco: un middleware gestisce centralmente gli errori, li scrive in Crashlytics e mostra un snackbar all’utente.

Riepilogo

  • Middleware è un pattern universale per isolare le preoccupazioni trasversali tra i componenti dell’applicazione, più ampio di Interceptor.
  • Redux middleware intercetta dispatch per logging, richieste asincrone (Thunk) e scenari complessi (Saga).
  • Ktor Client implementa il middleware tramite pipeline con plugin indipendenti Logging, Auth, ContentNegotiation.
  • BlocObserver è middleware per Flutter Bloc: onEvent, onTransition e onError gestiscono tutti i blocchi globalmente.
  • Dio Interceptor è HTTP-middleware per Flutter con una catena analoga a OkHttp Interceptor.
  • L’ordine di connessione del middleware determina la sequenza di elaborazione dei dati — documentalo esplicitamente.
  • L’uso corretto del middleware riduce la duplicazione del codice del 25-40% e semplifica i test unitari delle preoccupazioni trasversali.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche