Middleware — mezivrstva softwaru, která zpracovává data před nebo po hlavní logice aplikace a izoluje průřezové úkoly od obchodního kódu. Podle údajů Redux (2026), middleware snižuje duplicitu kódu pro protokolování a autentizaci o 40% díky centralizovanému zpracování. Redux middleware — klasický příklad, ale vzor se používá šířeji: Ktor Client, Bloc, Express.js a Dio.
Hlavní body
Middleware — softwarová vrstva umístěná mezi dvěma komponentami systému, která zachycuje a zpracovává data před předáním cílové komponentě. V mobilním vývoji se middleware používá ve třech hlavních kontextech: správa stavu (Redux, Bloc), HTTP komunikace (Ktor Client, Dio) a zpracování událostí (EventBus, NotificationCenter). Hlavní hodnota — izolace průřezových úkolů (protokolování, autentizace, analýza) od obchodní logiky aplikace. Místo přidávání volání analýzy na každou obrazovku to middleware dělá centralizovaně.
Middleware implementuje vzor Pipe and Filter: každá komponenta middleware přijímá data, zpracovává je a předává dalšímu článku řetězce. Pořadí připojení middleware určuje sekvenci zpracování — první middleware přijímá původní data, poslední je předává cílovému procesoru. Podle údajů JetBrains (2026), tato architektura umožňuje přidávat nebo vypínat middleware bez změny stávajícího kódu, což usnadňuje testování a A/B testování experimentálních modulů.
Middleware — obecný vzor, Interceptor — jeho konkrétní případ pro HTTP. Middleware pracuje s libovolnými datovými toky: actions v Redux, událostmi v Bloc, HTTP požadavky v Ktor. Interceptor je vždy vázán na síťovou vrstvu a pracuje pouze s Request/Response. Pochopení tohoto rozdílu pomáhá vybrat správnou abstrakci: pro protokolování akcí uživatele — middleware, pro přidávání hlaviček — Interceptor. Ve velkých projektech oba vzory často koexistují: middleware spravuje stav, Interceptor — HTTP komunikaci.
Redux middleware zachycuje každý dispatch action, než se dostane do reduceru. To umožňuje protokolovat akce, provádět asynchronní požadavky přes Redux Thunk nebo Redux Saga, upravovat action nebo jej podmíněně zrušit. Každý middleware obdrží store (přístup ke stavu), next (odkaz na další middleware nebo reducer) a action, a rozhodne, co dělat: předat action dál, upravit jej nebo zablokovat.
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]
);
Příklad analyticsMiddleware v Dartu pro Flutter Redux. Middleware zachycuje všechny NavigationAction, loguje název obrazovky do analytického systému a volá next(action) pro pokračování řetězce. Kdyby next nebyla zavolána, action by se nedostal k reduceru — tímto způsobem lze implementovat podmíněnou navigaci nebo blokování nežádoucích akcí. Pořadí middleware v poli určuje pořadí zpracování.
Redux Thunk — middleware umožňující dispatch nejen objektů action, ale také funkcí. Funkce obdrží dispatch a getState, může provádět async operace (API požadavky přes http klienta, čtení z databáze) a po dokončení dispatche obyčejné actions. To je standardní přístup pro práci se síťovými požadavky v aplikacích Redux. Redux Saga používá generátory (yield) pro složitější scénáře: rušení požadavků, race conditions, paralelní operace a debounce uživatelského vstupu. Podle údajů Redux Saga (2026), korutiny Saga se snáze testují a ladí než vnořená callbacky Thunku.
Ktor Client od JetBrains vytváří zpracování HTTP na základě pipeline middleware. Každá fáze požadavku — navázání spojení, odeslání hlaviček, čtení odpovědi — je reprezentována samostatnou fází v pipeline. Vývojář instaluje pluginy (middleware) pomocí client.install { }, čímž získá řetězec zpracování. Pořadí instalace určuje, který middleware zpracovává data jako první: Logging, Auth, ContentNegotiation, Caching.
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
}
}
Konfigurace Ktor Client s nainstalovanými middleware pluginy. Logging — zapisuje obsah požadavku a odpovědi. Auth — automaticky přidává Bearer token s podporou obnovení. ContentNegotiation — serializuje/deserializuje JSON. HttpTimeout — nastavuje časové limity. Každý plugin je nezávislý: v testovacím prostředí lze Auth vypnout změnou konfigurace klienta, aniž by se měnil kód požadavků.
Dio — populární HTTP klient pro Flutter, který používá Interceptor v roli middleware. Interceptor zachycuje RequestOptions před odesláním a Response po přijetí, podporuje řetězec několika zachycovačů. Dio Interceptor — obdoba OkHttp Interceptor pro Dart/Flutter. Podle údajů Dio (2026), RetryInterceptor a LogInterceptor jsou nejčastěji používané middleware ve Flutter projektech.
Bloc nemá vestavěný middleware jako samostatnou komponentu, ale vzor je implementován prostřednictvím BlocObserver — globálního pozorovatele, který přijímá události každého bloku v aplikaci. BlocObserver.onEvent je volán před zpracováním každé události, onTransition — při každém přechodu stavu, onError — při každé výjimce. Jedná se o plnohodnotný middleware pro analýzu, protokolování, hlášení chyb a monitorování výkonu.
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());
Příklad AppBlocObserver — middleware pro Bloc v Dartu. onEvent loguje každou událost do Crashlytics, onTransition odesílá události do analýzy, onError zapisuje výjimky do hlášení chyb. Připojení přes BlocOverrides.runZoned činí pozorovatele globálním pro všechny bloky bez změny jejich kódu. Pro vypnutí v testech stačí předat prázdného pozorovatele nebo nepřepsat BlocOverrides.
Middleware je účinný pro úkoly, které ovlivňují více komponent: protokolování, autentizace, analýza, ukládání do mezipaměti, monitorování výkonu. Používejte middleware, když se stejná logika opakuje v různých částech aplikace — přidávání tokenu ke každému požadavku, protokolování každé akce uživatele, analýza každého přechodu mezi obrazovkami. Podle údajů Dio (2026), centralizované zpracování přes middleware snižuje počet chyb o 25% ve srovnání s duplikováním kódu v každé komponentě zvlášť.
Nejčastější chybou — porušení pořadí middleware, kdy první zachycovač očekává data, která přidává druhý. Druhou nejčastější — blokující operace v middleware na hlavním vlákně: zápis do souboru, synchronní HTTP volání, šifrování. Třetí — nedostatečné zpracování výjimek: pokud middleware vyvolá výjimku, celý řetězec se přeruší a action se nedostane k reduceru nebo se požadavek neodešle. Vždy obalujte logiku middleware do try-catch a logujte chyby v Crashlytics nebo Sentry, aniž byste přerušili řetězec. Pravidelně kontrolujte řetězec middleware při revizi kódu — to zabraňuje degradaci architektury.
Často kladené otázky
Interceptor — konkrétní případ middleware pro HTTP komunikaci. Middleware — širší vzor: může zpracovávat akce (Redux), události (Bloc), HTTP (Ktor) a libovolné datové toky. Interceptor je vždy vázán na síťovou vrstvu a pracuje pouze s Request/Response.
Použijte tovární metodu nebo DI kontejner (Dagger, Koin, GetIt), který vrací jinou sadu middleware pro dev a prod. V Redux předávejte prázdné pole v testech. V Ktor — použijte testovací HttpClient bez pluginů. Hlavní zásada — middleware by neměl být pevně zakódován v aplikaci.
Ano — middleware upravuje action před předáním reduceru nebo dalšímu middleware. Například Redux middleware může přidat metadata (userId, timestamp, deviceId) ke každému action bez změny kódu dispatcheru. Hlavní pravidlo — nemutovat původní objekt, ale vytvořit nový pomocí spread operátoru.
V Ktor jsou termíny zaměnitelné — Ktor Client middleware a plugin znamenají totéž. Každý plugin implementuje HttpClientPlugin a instaluje se pomocí client.install { }. Všechny pluginy jsou vestavěny do pipeline požadavku a tvoří řetězec zpracování.
Přepsáním BlocObserver.onError — globálního handleru volaného při každé výjimce v libovolném bloku. To je alternativa k try-catch v každém bloku: jeden middleware centralizovaně zpracovává chyby, zapisuje je do Crashlytics a zobrazuje uživateli snackbar.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také