Middleware

Warstwa kodu działająca między żądaniem a odpowiedzią, przetwarzająca dane po drodze, np. uwierzytelnianie czy logowanie. Częsta w frameworkach serwerowych.

Middleware to warstwa kodu, która siedzi pomiędzy przychodzącym żądaniem a finalną odpowiedzią aplikacji i po drodze coś z tym żądaniem robi: sprawdza token, loguje, dokleja nagłówek, parsuje JSON albo odbija intruza. Zamiast wrzucać tę logikę do każdego endpointu z osobna, wpakujesz ją w jeden komponent, który framework uruchamia automatycznie dla wybranych tras. Termin bywa szerszy (oprogramowanie pośredniczące łączące systemy, np. szyny ESB czy brokery komunikatów), ale w codziennej pracy webdeva „middleware” to najczęściej właśnie ten przelotowy klocek w cyklu request-response.

Jak to działa

Middleware działa jak łańcuch (pipeline). Żądanie wchodzi, przechodzi przez kolejne ogniwa, dociera do właściwego handlera, a potem odpowiedź wraca tą samą drogą w drugą stronę. Każde ogniwo dostaje obiekt żądania i decyduje, czy przepuścić je dalej, zmodyfikować, czy zatrzymać i od razu odpowiedzieć (np. 401 Unauthorized). Kluczowa jest kolejność: middleware uruchamiają się w tej, w jakiej je zarejestrujesz.

Typowe zadania to uwierzytelnianie i autoryzacja, logowanie, obsługa CORS, kompresja, rate limiting, parsowanie ciała żądania czy globalne łapanie błędów. Dzięki temu logika „przekrojowa” (cross-cutting concerns) nie zaśmieca samej obsługi biznesowej.

Przykład z praktyki

W Express.js (Node) middleware to po prostu funkcja z trzema argumentami, gdzie next przekazuje sterowanie dalej:

app.use((req, res, next) => { console.log(req.method, req.url); next(); });

Jeśli zapomnisz wywołać next() i nie wyślesz odpowiedzi, żądanie zawiśnie — klient czeka, aż dostanie timeout. W Laravelu przypiszesz middleware auth do trasy, w Django masz MIDDLEWARE w settings, w ASP.NET Core budujesz pipeline metodami app.Use.... Idea wszędzie ta sama.

Częste błędy

  • Zła kolejność — np. rejestrujesz autoryzację po handlerze albo CORS po logice, która już zdążyła odrzucić żądanie.
  • Brak next() (lub jego odpowiednika) — wisząca odpowiedź i zagadkowy timeout.
  • Ciężka logika w globalnym middleware — odpalasz drogie zapytanie do bazy przy każdym żądaniu, także tam, gdzie wcale go nie potrzebujesz. Przypinaj middleware do konkretnych tras.
  • Mylenie pojęć — middleware to nie to samo co kontroler ani serwis. Ma robić jedną rzecz „po drodze”, nie obsługiwać całej domeny biznesowej.

Pojęcia powiązane

Warto skojarzyć middleware z cyklem request-response, wzorcem pipeline i chain of responsibility, dekoratorami, interceptorami (np. w Angularze czy Spring), filtrami serwletów oraz mechanizmem hooków. W kontekście integracji systemów obok pojawiają się message broker, API gateway i ESB.