Aplikacje w Koa.js są budowane przy pomocy zestawów funkcji zwanych middlewares. Dzięki takiej architekturze jesteśmy w stanie wydzielić logikę do poszczególnych funkcji i korzystać z tych samych funkcji w różnych projektach. Dziś o tym jak tworzyć takie funkcje by było to możliwe, na co uważać przy tworzeniu oraz jak łączyć je z innymi.
Inne wpisy o Koa
- Koa.js - pierwsze kroki
- Koa.js - obsługa błędów
Middlewares
To co będziemy określać jako middleware to będzie dowolna funkcja, która została zarejstrowana przy pomocy app.use. Nasza funkcja powinna przyjmować przynajmniej jeden parametr- zwyczajowo nazywany ctx (od context), gdzie znajdują się najważniejsze dla nas informacje oraz ustawiamy odpowiedzi na zapytanie. Tak jak wspomniałem w poprzednim wpisie Koa mocno poszła w nowości ze świata JavaScriptu więc mamy tutaj możliwość korzystania z funkcji asynchronicznych oraz awaita.
Context
Najważniejszą rzeczą w każdym middleware jest zmienna ctx. Jak wspomniałem przechowuje dla nas wszytskie informacje oraz umożliwia tworzenie odpowiedzi na zapytanie. Znajdziemy tam takie pola:
- req i res - są to natywne obiekty z Node'a - odpowiednio Request i Response
- request - obiekt Request z Koa
- response - obiekt Response z Koa
- app - zawiera referencję do utworzonej aplikacji
- cookies - pozwala na pobieranie i ustawianie cookies w aplikacji
- throw - pozwala na rzucenie błędu
- assert - pozwala na rzucenie błędu jeżeli przekazana wartość nie istnieje
Więcej o błędach i ich obsłudze będzie w innym poście.
Tworzenie własnych middlewares
Najprostszy sposób na stworzenie własnego middleware'a to stworzenie zwykłej funkcji oraz zarejestrowanie jej w aplikacji.
Kiedy tworzymy takie funkcje to chcemy je wykorzystywać w wielu miejscach - warto wtedy dać możliwość ustawiania opcji by można było dopasować funkcję do aktualnych potrzeb.
Nawet jeżeli nasz middleware nie przyjmuje opcji to jest zalecane aby dalej utrzymywać taką strukturę.
Przechodzenie pomiędzy middlewares
Została ostatnia rzecz jeżeli chodzi o middlewares czyli przechodzenie pomiędzy różnymi stworzonymi przez nas funkcjami. Do tej pory mieliśmy zarejestrowany jeden middleware który od razu zwracał odpowiedź na zapytanie - jednak w prawdziwych aplikacjach będziemy ich mieć o wiele więcej. Przy komponowaniu naszych funkcji musimy pamiętać o kilku rzeczach.
Po pierwsze wszystkie funkcje są wywoływane w kolejności w jakiej je rejestrujemy - warto o tym pamiętać ponieważ kolejność czasami może mieć znaczenie.
Następna rzecz to przynajmniej jedna z funkcji powinna ustawiać ciało odpowiedzi - o ile więcej niż jedna funkcji to ustawia, to ciało odpowiedzi będzie równe ostatniemu ustawieniu.
Ostatnia rzecz o jakiej warto pamiętać to, iż jeżeli nasza funkcja nie ustawia odpowiedzi to musimy przejść do kolejnej funkcji. Robimy to przy pomocy drugiego parametru funkcji - next. Jest to funkcja która odsyła sterowanie do następnego middleware'a.
Po wykonaniu zapytania w konsoli pojawi się po kolei następująca sekwencja
Możemy również odwrócić kolejność wywoływania console.log() jeżeli najpierw wywołamy next(). W momencie gdy wykonamy wszystkie middlewary to wykonywanie funkcji wraca do poprzednich funkcji i jest wykonywany kod, który pozostał po funkcji next(). Najlepiej to będzie widać na przykładzie:
Teraz w konsoli będzie następująca sekwencja
Z jednej strony jest to interesująca opcja, ponieważ jesteśmy w stanie osiagnąć różne rzeczy np.: mierzyć statystyki (np.: czas) dla zapytań. Z drugiej strony debuggowanie może być problematyczne jeżeli o tym zapomnimy. To co dzisiaj omówiłem jest najważniejszym elementem Koa i wystarczająca do tworzenia aplikacji. Następnym razem opiszę jak reagować na błędy aplikacji.