w Praktyce
10 godz. 44 min · Node.js · Full-stack i Programowanie
Piotr PalarzWeb DeveloperW kursie tym poznasz platformę Node.js od podstaw, aż po bardziej zaawansowane koncepcje. Zaczniemy od omówienia czym jest Node, a także jakie może być zastosowanie tej technologii. Następnie przejdziemy przez proces instalacji i napisanie swojego pierwszego skryptu. Już na samym początku dokładnie omówimy tworzenie własnych modułów, gdyż jest to wiedza niezbędna, by dobrze zrozumieć funkcjonowanie Node. Następnie dowiesz się czym są zdarzenia, jak działa model “publish / subscribe”, a także czym jest “event-driven development”. Chwilę później omówimy pracę z buforami, stream’ami, a także ze standardowym wejściem i wyjściem. Ta wiedza pozwoli Ci zrozumieć jak tworzone aplikacje mogą otrzymywać od użytkownika dane oraz jak je wyświetlają.
Niezwykle ważnym rozdziałem będzie ten, poświęcony pracy z systemem plików. Szczególnie dla dewelopera, pracującego dotychczas z językiem JavaScript wyłącznie w środowisku przeglądarki internetowej. Node pozwala bowiem tworzyć nowe pliki, zapisywać w nich dane oraz odczytywać i usuwać pliki i katalogi. Przy wszystkich tych operacjach, niezwykle ważna jest jednak asynchroniczna natura Node. Dowiesz się jak działa, a także jakie są jej zalety. Na tym etapie nie zabraknie oczywiście praktycznego projektu, którym będzie aplikacja typu CLI (Command Line Interface). Pozwoli nam ona grupowo zmienić nazwy wielu plików, według podanego wzorca.
W kolejnym rozdziale poruszymy fundamentalną dla Node kwestię, mianowicie tworzenie serwerów sieciowych. Zaczniemy od najniższego poziomu, tworząc prosty serwer bazujący na protokole TCP/IP. Wiedza w jaki sposób Node radzi sobie z takim zadaniem, pozwoli później lepiej zrozumieć wyższe warstwy, takie jak np. HTTP czy WebSockets. Chwilę później stworzymy swój pierwszy serwer HTTP, do którego będzie można wysyłać zapytania wprost z przeglądarki internetowej. Omówimy również jak w Node wykorzystać bezpieczne szyfrowanie HTTPS.Na tym etapie będziesz już miał solidną wiedzę jak pracować z Node, jednak zanim przejdziemy dalej, zatrzymamy się, by omówić jak dokładnie działa Node.js, a także jak ta platforma została zbudowana. Dwie dość obszerne lekcje, będą być może jednymi z najważniejszych w tym kursie. Dowiesz się w nich czym jest, a także jak działa jednowątkowa pętla zdarzeń, czym jest proces i wątek, a także zobaczysz kod źródłowy Node.js i wszystkie bloki budulcowe, z jakich Node się składa. To naszym zdaniem niezwykle ważny temat, często jednak pomijany w wielu materiałach. Dzięki dogłębnemu zrozumieniu jednowątkowej natury języka JavaScript i asynchroniczności Node, będziesz mógł tworzyć dużo lepsze aplikacje.
Node.js posiada kilkanaście wbudowanych modułów, z których w dowolnej chwili można skorzystać. Wszystkie jednak dają nam dużą, niskopoziomową kontrolę, ale czasami sporo kodu należy napisać, by zrealizować jakieś zadanie. Jest to jednak świadomy wybór twórców Node, gdyż całą resztę świetnych rozwiązań, dopisuje nieustannie ogólnoświatowa społeczność deweloperów. Zdecydowana większość z modułów ląduje w rejestrze npm. Jest to genialny package manager, który pozwoli nam wyszukiwać, pobierać i aktualizować niezliczoną ilość modułów. Dowiesz się zatem jak korzystać z npm, a chwilę później zaczniemy wykorzystywać zgromadzone tam moduły w dalszej pracy.Jednym z najpopularniejszych modułów jest express.js, który pozwala w bardzo prosty sposób tworzyć serwery HTTP. Grzechem byłoby zatem z niego nie skorzystać. Dowiesz się wszystkiego co niezbędne, by zacząć tworzyć własne aplikacje bazujące na protokole HTTP z użyciem express.js, a także kilku dodatków do tego systemu. Zobaczysz jak routować zapytania, jak korzystać z middleware czy serwować statyczne pliki. Następnie omówimy współpracę z bazą danych MongoDB i z jej wykorzystaniem stworzymy API typu REST. Stworzona aplikacja pozwoli odczytywać dane z bazy i przesyłać je do klienta w formacie JSON, a także dodawać nowe dane, aktualizować i usuwać je. Wszystko to zgodnie z dobrymi praktykami pracy z REST.
Chwilę później czeka Cię kolejny praktyczny projekt - skracacz linków. Stworzymy wspólnie aplikację, która pozwoli skrócić dowolny adres URL do krótkiej formy. Oczywiście będzie działać również w drugą stronę! Kiedy przejdziemy pod skrócony adres, przekieruje nas do odpowiedniej witryny. Node.js to platforma wręcz stworzona do tworzenia aplikacji typu real-time, dlatego w kolejnym rodziale podejmiemy temat technologii WebSockets. Dowiesz się jakie są jej zalety, a także jak pracować z nią po stronie serwera i klienta. Tutaj czeka nas kolejny praktyczny, niezwykle ciekawy projekt. Wykonamy bowiem czat grupowy. Aplikacja ta pozwoli dowolnej ilości użytkowników podłączyć się do czatu podając swój nick, a następnie wysyłać widoczne dla wszystkich wiadomości. Zaimplementujemy nawet takie rozwiązania jak wyświetlanie statusów o dołączeniu kogoś do czatu, a także o jego opuszczeniu.W przedostatnim rodziale tego kursu podejmiemy tematykę dobrych praktyk pracy z Node.js. Na początku omówimy najważniejsze konstrukcje nowej specyfikacji EcmaScript 2015, które są znakomicie wspierane w Node. Chwilę później omówimy jak korzystanie z Promises uprości, a także ulepszy nasz kod. Wśród dobrych praktyk nie zabraknie również informacji o debugowaniu aplikacji. Zobaczysz sprawdzone sposoby, by znaleźć błędy lub lepiej, krok po kroku, zrozumieć jak działa napisany wcześniej kod. Dowiesz się również jak pracować z błędami, by Twoje aplikacje działały w sposób przewidywalny.
Ostatni rozdział w całości został poświęcony temu, co zwykle jest pomijane w innych materiałach, mianowicie wdrażaniu aplikacji do produkcji. Przez cały ten kurs pracować będziemy lokalnie, lecz kiedy aplikacje są już gotowe, wypadałoby udostępnić je światu. Wdrażanie aplikacji napisanych z użyciem Node.js nie jest jednak tak oczywiste, jak np. wgrywanie WordPress’a u wybranego hostingodawcy. Ty będziesz miał jednak możliwość zobaczyć, jak wdrożyć napisany przez nas grupowy czat na platformie Heroku. Jest to bardzo popularny serwis działający jako PaaS (Platform as a Service). Za darmo będziesz mógł w ciągu kilku chwil uruchomić swoją aplikację.Zobaczysz o co należy zadbać, by wszystko poszło gładko. Serwisy typu PaaS dbają o bardzo wiele aspektów wdrażania i serwowania naszych aplikacji, takich jak bezpieczeństwo oraz nieustanną dostępność. Mają jednak pewne ograniczenia. Z tego powodu, dowiesz się również jak wdrożyć swoją aplikację na serwerze wirtualnym VPS z systemem Ubuntu Server. Takie rozwiązanie daje nam całkowitą kontrolę, ale także obarczone jest większą odpowiedzialnością. Zaczniemy od instalacji na serwerze platformy Node.js, systemu kontroli wersji GIT, a także innych niezbędnych modułów
Następnie zobaczysz jak skonfigurować swoje lokalne środowisko tak, by za pomocą GIT’a wysyłać kod do zdalnego serwera, a potem jednym poleceniem wdrażać go do produkcji. Dowiesz się również jak jednocześnie serwować wersję produkcyjną oraz developmencką. W rodziale tym poruszymy również inne kwestie, takie jak procesy potomne czy tworzenie klastrów. Dzięki tej wiedzy, będziesz mógł maksymalnie wykorzystać dostępne zasoby serwera. Na sam koniec tego kursu rzucimy okiem również na inne, nie przedstawione wcześniej zastosowania Node, a także nakreślimy dalszą drogę nauki w tym zakresie.
Kurs ten jest dla wszystkich osób, które dobrze czują się w technologiach frontendowych, tj. HTML, CSS i JavaScript, a teraz chcą rozpocząć swoją przygodę z back-endem. Im zatem lepiej znasz język JavaScript, tym więcej wyciśniesz z Node, natomiast nie jest wymagana bardzo zaawansowana wiedza z zakresu tego języka.
W tej lekcji pokażę ci, czym w Express jest middleware i co ciekawe - z middleware'ów już korzystaliśmy w Expressie
do tej pory.
Natomiast przejdźmy od razu do rzeczy.
Mamy taki prosty serwer. Na początek wykonamy npm install.
Robię to tylko po to, abyś ty również pamiętał, że nie mamy jeszcze katalogu node_modules i mielibyśmy błąd.
Teraz jeżeli wpiszę nodemon index, to nasz serwer powinien się uruchomić.
I tutaj powinien działać.
Mamy stronę główną - jest wszystko w porządku. Natomiast być może pamiętasz, że za każdym razem Express wysyłał
nam taki tag jak tutaj - X-Powered-By - i w zasadzie to nazywa się nagłówek. Pokazywałem ci, że jego można wyłączyć
za pomocą app.disable.
Więc jest to najprostsza metoda. Ale chcę ci na jego przykładzie pokazać, jak działają middleware i gdybyśmy
nie mieli takiej metody do jego wyłączenia, to moglibyśmy to zrobić za pomocą remoweHeader. Pokazywałem ci
że możemy się odwołać do res.removeHeader i usunąć nagłówek X-Powered-By.
W ten sposób. Zerknijmy, czy wszystko wpisałem poprawnie. Jeżeli teraz odświeżę, to on powinien zniknąć.
Tak też się stało. Natomiast jeżeli będziemy tutaj mieli więcej zapytań, to chciałbym dla każdego z nich
dla takiej ścieżki wykonywać taką linijkę kodu, więc możemy to zrobić.
To jest tylko przykład, ale tutaj będziesz mógł robić rzeczy dowolne. Mianowicie odwołamy się do app.use.
I ważne jest, żeby to było zdefiniowane wcześniej.
I tutaj mówiłem ci już, że podajemy funkcję, która ma się wykonać dla każdego połączenia. W tym przypadku
dla każdego ona będzie miała request, response i to, co jest ważne, to jeszcze parametr next.
W zasadzie to wszędzie tutaj będzie parametr next.
Ale on nie jest nam konieczny.
Dlatego przejdźmy sobie tutaj do tej funkcji.
I powiem ci, na czym sprawa polega.
Otóż kiedy przejdziemy pod ten serwer, tak jak tutaj, to wyobraź sobie, że najpierw ta funkcja zostanie
wykonana, a dopiero później następne.
Natomiast następna funkcja, w tym przypadku ta get, bo pasuje nam ta ścieżka, nie zostanie wykonana, jeżeli
nie wykonamy next. Czyli tu możemy robić różne rzeczy, nawet asynchroniczne, ale w którymś momencie
musimy wykonać next, bo inaczej serwer nam się tutaj zawiesi, czyli cały czas będzie się kręcić w przeglądarce,
aż nie minie jakiś tam czas określony timeoutem.
Dlatego tutaj będę chciał zrobić res.removeHeader i następnie next.
Możemy to zrobić tak. I teraz jeżeli odświeżę, wszystko działa od razu poprawnie, ale usunęliśmy sobie ten
nagłówek.
No i ważne jest to, że taki middleware, bo tak to się nazywa, będzie działał dla wszystkich ścieżek, nieważne
jakie ścieżki tutaj zdefiniuję.
Z tego powodu pokażę ci pewną ciekawostkę, która pozwala nam przekazywać parametry jakby z jednej funkcji
do drugiej. Możemy odwołać się do res.locals.
Mamy taką zmienną. I tutaj możemy dodać, co chcemy.
Jest to obiekt, więc napiszę data i napiszę "Dane dodane wcześniej", a tutaj możesz tak naprawdę przypisać
co chcesz.
Dzięki temu, że to dopisałem w tym miejscu, to tutaj gdzie mamy res.send, template tag czy template string,
to będę mógł tutaj dopisać sobie response i następnie locals.data.
Jeżeli to sobie odświeżymy, to nam się to również tutaj pojawi.
Czyli możesz stworzyć różne middleware i takie middleware może podopisywać sobie różne rzeczy do response czy request.
Najlepiej właśnie do locals, bo do tego służy ten obiekt, i później z niego korzystać.
Natomiast tutaj, jak widzisz, możemy ustawić jakieś nagłówki czy te nagłówki powiedzmy usunąć.
To jest pierwsze zastosowanie takiego middleware.
Natomiast teraz chciałbym stworzyć inne.
Będzie to taki pseudokod, jeżeli chodzi o logowanie się do admina.
Nie będzie on zbyt bezpieczny, nie polecam ci, abyś z tego korzystał, ale chcę ci pokazać samą ideę, bo
znajdziesz do Expressa również bardzo wiele dodatkowych modułów, które pozwolą nam np. logować się do
serwisu czy obsługiwać ciasteczka.
One wszystkie będą korzystać właśnie z middleware w podobny sposób.
Na początek chcę utworzyć dwie stałe.
Jak widzisz, będzie to użytkownik i jakieś bardzo trudne do odgadnięcia hasło.
I teraz będę chciał stworzyć sobie ścieżkę, więc skopiuję to, co jest tutaj, i będzie to ścieżka admin.
I tutaj będę chciał odesłać po prostu res.send i napiszemy "Zaplecze administratora".
Standardowo jednak będzie można do niego przejść.
W ten sposób. Nie ma problemu.
Natomiast chciałbym utworzyć middleware, który będzie dla admina się wykonywać.
Nie chcę w tym miejscu tego obsługiwać, chociaż mógłbym.
Chcę, żeby ta funkcja była czysta.
Dlatego teraz utworzymy sobie middleware za pomocą app.use i nie podam tutaj funkcji, tak jak wcześniej,
ale najpierw podam ścieżkę.
Jest to bardzo ważne i napiszę admin. W ten sposób. I dopiero teraz funkcję, która przejmie request, response
oraz next.
I w tej funkcji będę mógł sobie sprawdzić, czy ktoś podał hasło i użytkownika.
Natomiast to, co jest bardzo ważne w tym przypadku, to ten middleware wykona się tylko dla właśnie admin,
czyli dla tego, co widzisz w tym miejscu.
Jeszcze jedna ważna uwaga jest taka, że w miejscu gdzie robiliśmy np. get/ albo gdyby tutaj było
o nas, to oznaczało to, że musi to być dokładna ścieżka. Nie mogło być tutaj o nas zapisane w ten sposób
czy nie mogło być np. o nas i tutaj cokolwiek innego.
Natomiast w przypadku app.use to, co podajemy tutaj, nie jest to dokładna ścieżka, tylko jej przedrostek. To znaczy, że
jeżeli tutaj mam admin i dalej miałby np. panel, to ten middleware, jeżeli podam tylko /admin, również
będzie dla tamtej ścieżki wykonywany. To jest ważne, że to jest tylko przedrostek.
Jeżeli zrobimy tak, no to jest dokładnie to samo.
I teraz wpadłem na niezbyt rozsądny pomysł, aby te dane przesyłać nawet nie za pomocą pose, jak to jest
zazwyczaj, kiedy się logujemy, ale za pomocą query stringu
w tym miejscu. Chciałbym, żeby to było przekazywane tutaj, a więc sprawdzimy to w ten sposób.
Czyli jeżeli query.user będzie równy użytkownikowi admin, jeżeli query.password będzie równe password,
to wtedy zrobimy next.
Pamiętasz, że next wykona kolejną funkcję, w tym przypadku będzie właśnie to ta funkcja.
Natomiast w przeciwnym wypadku, czyli będziemy w tym miejscu,
jeżeli to nie będzie poprawne, to pokażę ci ciekawą metodę res.redirect.
Kolejna świetna metoda dostępna w Express, która zadba o ustawienie np. odpowiedniego status kodu na
302 itd.
Możemy tutaj przekierować i przekierujemy sobie do strony głównej. Czyli jakby podstawy logowania mogą
wyglądać mniej więcej w ten sposób, ale nie korzystaj z tego w żadnym wypadku.
Mamy stronę główną, mamy admin. No i do admina
nie da się przejść. Jak widzisz, przekierowuje nas, a widzimy tutaj w panelu Network, że było to przekierowanie
ze statusem
302.
Gdybyśmy kliknęli, to będziemy mogli zobaczyć Location: /,czyli właśnie tutaj nas przekierowało.
Jak widzisz, Express dba o to, żeby dodać np. taki nagłówek.
Nie musieliśmy w ogóle o tym myśleć.
Tak naprawdę nawet nie musieliśmy wiedzieć, że takie nagłówki są potrzebne. W przypadku modułu http w Node
byłoby to bardziej skomplikowane, bo musielibyśmy to wszystko zrobić ręcznie.
Natomiast jeżeli tutaj sobie podamy admin i następnie user równa się admin i password równa się 1234,
to jesteśmy w zapleczu administratora.
Teraz udało nam się wejść.
Jak zatem widzisz, taki middleware może nam ukryć jakąś część naszego serwisu.
Natomiast ważne jest to, że tak naprawdę działałoby to w dużo bardziej zaawansowany sposób, czyli logowalibyśmy się,
tutaj byśmy sprawdzali, czy podane przez użytkownika dane na pewno nie w taki sposób, tylko posem
są gdzieś w bazie danych, czy taki użytkownik istnieje -
jeżeli tak, to byśmy ustawili jakąś sesję za pomocą ciasteczek itd. Są to tematy bardziej zaawansowane
i do tego wszystkiego znajdziesz odpowiednie moduły.
Na sam koniec chcę ci jeszcze pokazać, że do Expressa możemy znaleźć całe tony takich middleware przydatnych
do różnych rzeczy. I teraz jedno z nich będę chciał ci pokazać. Zauważ, że mamy tutaj katalog public, w którym
mamy images. Mamy tutaj różne obrazki i chciałbym móc je teraz odpowiednio serwować.
Nigdzie tutaj nie definiowałem public, więc nie możemy odwołać się do /images. Możemy spróbować.
No i widzimy Cannot GET /images/. Natomiast pokażę ci teraz bardzo ciekawy middlewar, który nazywa się serve index.
Wyszukamy go teraz tutaj.
I tak naprawdę nawet nie jest to middleware dla Expressa, ale middleware dla Connecta.
No i teraz czym jest Connect? Pokażę ci jeszcze szybko stronę tego projektu.
Otóż Connect jest to taki framework, na bazie którego został zbudowany Express.
Jest on nieco bardziej uproszczony i właśnie on opiera się na takiej zasadzie middlewares, czyli to, co
ci pokazuję teraz, takie middlewares,
to zostały zapoczątkowane w Connect.
Możesz sobie o tym przeczytać tutaj. I ważne jest to, że każdy middleware napisany dla Connecta działa
poprawnie również z Expressem. Dlatego serve index sobie teraz zainstalujemy. Ctrl+C - zatrzymujemy serwer.
Npm install serve-index --save. Ok.
Zainstalowało się to, więc nodemon index, żeby wrócić do serwera.
Teraz przejdziemy do edytora i w tym miejscu będę chciał sobie to zainkludować. Require("serve-index").
Oczywiście muszę nazwać jakoś stałą. W ten sposób. I zaraz ci wytłumaczę, jakby na czym to polega.
Bo zamiast tłumaczyć, to po prostu ci to pokażę.
Przejdźmy sobie tutaj niżej i zrobimy pierwsze to, co robiliśmy wcześniej, czyli app.use.
I nie wiem, czy pamiętasz, ale zapewne tak, to korzystaliśmy z express.static, abyśmy mogli serwować statyczne
pliki. Chciałbym je serwować z katalogu public.
Ale teraz to, co jest niesłychanie istotne, możemy ustawić ścieżkę, dla jakiej będzie takie serwowanie.
Czyli mogę tutaj napisać /files. Jest to o tyle fajne, że wcześniej ci pokazałem, że jeżeli wpiszemy takie polecenie,
czyli express.static("public"), no to będziemy mogli pobierać pliki z tego katalogu public.
Ale jeżeli wpiszemy tutaj najpierw ścieżkę, to one będą dostępne pod /files i dopiero później np.
images.
Bardzo fajna sprawa i teraz skorzystamy z serve index,
zobaczysz, na czym sprawa polega.
App.use - również musimy tutaj napisać /files - w ten sam sposób.
I teraz serveIndex.
I tutaj napiszemy public, czyli to samo, ale obydwie te linijki są potrzebne.
Teraz nasz serwer działa tak samo jak wcześniej.
Ale jeżeli przejdziemy do files, to wczytał nam się nasz middleware serve index
i zauważ, że jest on od razu ładnie ostylowany.
Możemy tutaj klikać i wyświetlać sobie poszczególne rzeczy.
Gdybym nie wpisał tej linijki tutaj, to nie moglibyśmy przejść do ostatniego kroku, czyli to wszystko
by nam się wyświetlało,
ale nie mógłbym już przejść do obrazka.
I zauważ, że ścieżka jest to files/images itd, a na serwerze jest to tak naprawdę w katalogu public.
Podobne rozwiązanie często można spotkać na serwerach Apache.
Kiedy mamy pliki w katalogu, to domyślnie są one serwowane w taki sposób.
Tutaj nie działa to domyślnie, musieliśmy do tego przypisać sobie odpowiedni middleware,
ale, jak widzisz, wszystko jest możliwe.
Gwarantuję ci że takich middleware'ów możesz znaleźć całą masę.
I pamiętaj, że wszystkie, które będą opisane jako działające z Connectem, działają również z Expressem.