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 wykorzystamy wiedzę już posiadaną z zakresu Express, tworzenia API, a także MongoDB i stworzymy
praktyczny projekt skracacza linków. Jak on będzie działał? Zaraz zobaczysz. Natomiast na początek zauważ,
że mamy w pliku package.json dependencies, express i mongoose, z których będziemy korzystać. Więc chciałbym je zainstalować
poprzez npm install i uruchomimy sobie od razu serwer nodemonem. Bo zaraz ci pokażę, że ten serwer istnieje.
Wpiszę od razu nodemon index. Działa. Poczyniłem pewne kroki, mianowicie stworzyłem sobie taki prosty serwer.
Nie ma tutaj nic, czego byś nie znał.
Natomiast importuję sobie tutaj api, które stworzyłem w katalogu api.
Tutaj. Jeżeli przejdziemy do tego pliku, to tyle mamy na początek. Pobieramy Mongoose i następnie tworzymy
kilka stałych. I będziemy chcieli się połączyć z bazą danych dokładnie taką samą, jak mieliśmy w lekcji
poprzedniej. Więc zaloguj się do swojego mLaba i skopiuj cały ten URL, który jest w tym miejscu, i odpowiednio
go sobie tutaj podstaw.
Dodatkowo stworzyłem stałą WEBSITE_URL, która nam się przyda później.
Teraz chcę ci wytłumaczyć, jak będzie działał nasz skracacz linków. Mianowicie chciałbym móc przejść pod taki
adres, następnie pod api i shorten.
I tutaj chciałbym podać URL w ten sposób, np. http://eduweb.pl i chciałbym, żeby to API skróciło go i mi zwróciło.
Więc jak to będzie działać? Zobaczysz za sekundę.
Ale to już mówi nam, że chcemy utworzyć sobie w Expressie taką ścieżkę api/shorten.
Dlatego będąc tutaj, zróbmy to od razu.
App.get - wiemy, że będzie to zapytanie typu get, /api/shorten.
Jeżeli chcemy tutaj queery string, to nic nie podajemy w tym miejscu, ale będziemy musieli go walidować
za chwilę na request.
Jak to zatem będzie wyglądać?
Otóż do tego api, które mamy tutaj - zaraz je będziemy uzupełniać -
chciałbym dodać metodę shorten, z której mogę korzystać tutaj. Więc korzystamy z niej, zanim ją stworzymy.
Api.shorten - chciałbym jej przekazać req., query.url.
Już wiesz że pod tym query.url będzie właśnie ten ciąg.
Jeżeli wpiszemy sobie tutaj url. Jeżeli nie, to nie, ale to będziemy walidować później i z uwagi na fakt, że to będzie
działać w sposób asynchroniczny, to będziemy chcieli wykonać tutaj funkcję.
Czyli kiedy to się uda zrobić, wykonaj funkcję typu error-first callback.
Będzie błąd, to będzie tutaj.
Jeżeli nie, to zwróć mi
krótki link, który wygenerowałeś. Zaraz sobie to uzupełnimy, ale ja od razu wrzucę tutaj cały kod.
Nie ma tutaj nic nowego. Jeżeli ta nasza funkcja, którą za moment stworzymy - shorten - zwróci błąd, to chcę odesłać res.json,
error: true i chciałbym mieć tutaj treść tej wiadomości.
Tak sobie to wymyśliłem.
Natomiast jeżeli nie będzie błędów, to chcę odesłać error: false, a pod short chce mieć ten skrócony URL.
Bardzo prosta sprawa.
Natomiast teraz aby sobie to zaimplementować, to musimy przejść do metody shorten - tutaj do api - i po prostu ją
utworzyć.
Przejdźmy sobie tutaj niżej.
Metodę nazwę shortenURL. Ona przyjmie właśnie ten query.url, który tam przed momentem przekazaliśmy i
callback do wykonania.
Zaraz ją uzupełnimy, ale na końcu musimy zrobić module.exports. Tu będziemy jeszcze jedną metodę później
eksportować, więc na razie zrobię to tak. Napiszemy shorten, bo z takiej tam korzystałem.
I tu będzie shortenURL po prostu. Ok. Czyli wyeksportujemy shorten, z którego skorzystałem tutaj. Przyjmuje
URL, a także funkcję callback. Czyli cała ta funkcja tutaj będzie pod cb, no i będziemy mogli tutaj pracować.
Natomiast zanim to zrobimy, to chcę ci pokazać, jaki schemat utworzymy sobie w bazie danych MongoDB.
Tutaj wcześniej mieliśmy już users, a teraz chciałbym mieć kolekcję urls,
dlatego w znany tobie już sposób tutaj utworzymy sobie nowy schemat.
Napiszę schema = new mongoose.Schema i chciałbym, żeby przechowywane dokumenty w naszej bazie danych o
takim jednym linku, czyli ktoś w naszym shortenerze skróci sobie link, to chciałbym, żeby one przechowały
oczywiście oryginalny adres URL takiego linku, bo będziemy później z niego korzystać, oraz skróconą jego
wersję. Czyli chciałbym mieć tutaj short.
I będzie to string. A także url i to również będzie string.
Zaraz się to wszystko rozjaśni. I teraz chcemy na bazie tego utworzyć model, który ja nazwę URL i odwołamy się
tutaj do mongoose.model, podajemy jego nazwę - napiszę URL. Tutaj te wielkie litery nie do końca mają
znaczenie, natomiast z tego zostanie utworzona nasza kolekcja tutaj na zapleczu, która będzie się nazywała
URLS, czyli s zostanie dodane zostanie na końcu. I to dla nas jest w porządku, więc nie musimy tego zmieniać. I podamy
po prostu schema. I teraz zajmiemy się metodą shortenURL, w której przekazujemy URL i callback.
Pierwsza rzecz, którą chciałbym zrobić, to jeżeli tutaj przekażemy URL -
albo inaczej mówiąc, w tym miejscu przekażemy URL niepoprawny albo go nie przekażemy w ogóle -
powiedzmy, że napiszę coś takiego. Jak widzisz, teraz nam to nie działa tutaj, bo ta metoda nic nie zwraca,
więc tutaj zaraz będzie time out.
Ale o co chodzi?
To będzie w tym miejscu pod req.qurty.url przekazane do shorten.
Czy chciałbym w tej metodzie shorten
pierwszą rzeczą, jaką zrobimy, to sprawdzić, czy URL jest poprawny.
No i teraz mógłbyś zapytać jak to zrobić?
Po to mamy npm, żeby wyszukać,
więc zróbmy to sobie. Albo nawet wejdziemy po prostu w Google i wpiszemy po prostu validate url npm.
Mówiłem ci, że dobrze jest w Google wyszukiwać, więc zobaczymy.
Przejdźmy sobie pod pierwszy wynik - valid-url.
Zobaczymy, co to jest za metoda. Jak widzimy, ona nam pozwala walidować tutaj, czy dany string jest URL-em,
czy nie.
Wydaje się, że jest w porządku.
Tutaj było całkiem sporo pobrań, więc możemy zainstalować ten moduł npm install valid-url. Zatrzymam serwer
Ctrl+C, wpiszę npm install save, zainstalujemy to sobie i pierwsze, co będę chciał zrobić, to sobie to
zaimportować
tutaj na samej górze
Ja sobie to tak nazwę i już mamy taki moduł. Więc możemy z niego skorzystać tak, jak jest to tutaj napisane,
czyli validUrl.isUri i przekazujemy tam string.
No to zróbmy sobie to tutaj prostym if. Natomiast żeby nasz kod był jeszcze bardziej modułowy, to stworzymy
sobie do tego funkcję. Czyli tutaj chcę powiedzieć: jeżeli validateURL i przekazujemy value, w zasadzie to
url, jeżeli nie jest poprawny, to będę chciał zakończyć tę funkcję i wywołać nasz callback.
Przypominam, że callback jest tutaj, więc chcę go wywołać, przekazując mu error.
No i wtedy ten error, czy w zasadzie jego właściwość message, zostanie przesłane jsonem dalej. Więc chcę wywołać callback
i napiszemy sobie tutaj new Error.
Tworzymy nowy obiekt Error i napiszę sobie: URL is not valid.
Zauważ, co tutaj się stanie. Po pierwsze zakończy się funkcja, po drugie wykonamy callback, przekazując nowy
obiekt error. Czyli ten callback się wywoła, a pod error będzie miał ten obiekt.
No i skoro stworzyliśmy new Error, to ma on właściwość message, która jest dokładnie w tym miejscu, i zostanie
to odesłane.
Więc tak to zrobimy. Ale chcę sobie stworzyć wcześniej funkcję validateURL. Lepiej to tak podzielić, chociaż
nie musimy wcale tego robić. I z niej zwrócimy właśnie odwołanie do tego validURL.isUri(url), czyli dokładnie
to, co jest na stronie tutaj opisane,
to nam zwróci tutaj. No i będziemy to mogli odesłać. Teraz sobie uruchommy nasz serwer.
I spróbujmy podać niepoprawny adres, tak jak to tutaj zrobiłem.
Zobaczmy. No i dokładnie wszystko działa - json error: true, message: URL is not valid został nam odesłany.
Czyli wszystko jest w porządku. Natomiast jeżeli podamy poprawny URL, to ten return się nie wykona i
przejdziemy poniżej. Ale wiemy już, że pod URL jest poprawny URL, więc możemy go skrócić i zapisać w bazie
danych.
Logika tego będzie następująca.
Otóż chcę się odwołać do bazy danych MongoDB i sprawdzić, czy taki URL już tam jest.
No bo wyobraź sobie, że skorzystał ktoś z naszego shortenera i skrócił sobie taki oto adres http://eduweb.pl.
No i teraz ktoś inny też chce zrobić taki adres.
No to najlepiej byłoby sprawdzić, czy w bazie danych przypadkiem ktoś już nie skracał takiego URL-a. Jeżeli
tak, to po prostu zwróćmy to, co już tam jest.
Dlatego odwołamy się do naszego modelu URL.findOne.
Jest to również metoda dostępna w Mongoose.
i w MongoDB. I chcemy znaleźć dokument, który - tutaj podajemy jego kryteria - który ma url równe temu
url przekazanemu tutaj. Bo na tym etapie już wiemy, że on jest poprawny.
Czyli tu będziemy mieli np. http://eduweb.pl. Definiowaliśmy wcześniej, że właśnie taki jeden dokument ma mieć
url oraz short.
Tym się zajmiemy za moment. Czyli próbujemy znaleźć taki dokument. Zrobimy exect i funkcja, która przyjmie
error, oraz znaleziony dokument, czyli po prostu url. Żeby nam się te URL-e tak nie myliły, to może tutaj
do shortenUrl przekażemy sobie po prostu value. To i tak nam zadziała, nie ma problemu, ale będzie to bardziej
czytelne.
Czyli tutaj będzie przekazywane value.
I tu też możemy napisać value. Chociaż w zasadzie niech tutaj zostanie url.
Tak czy siak by to działało, ale teraz będzie bardziej czytelne.
Czyli jeżeli w bazie danych MongoDB taki URL eduweb.pl już był,
to możemy to sprawdzić. Natomiast wcześniej sprawdzimy, czy jest błąd.
Jeżeli był błąd, to chcemy zakończyć, czyli return. I wywołać callback
z tym właśnie błędem. I zauważ, że tutaj tworzyłem swój błąd, który był wywoływany w tym miejscu, czy w
zasadzie odsyłany.
Natomiast jeżeli URL będzie poprawny, ale tutaj wystąpi błąd, to tak samo callback z błędem się wykona i
znowu tutaj error message będzie można odesłać, tak jak to zrobiliśmy w tym miejscu.
Ale będzie to jakiś błąd, który został wygenerowany przez MongoDB.
Zatem w tym miejscu, jeżeli nie było błędu, to znaczy, że znaleźliśmy lub też nie jakiś URL już w bazie
danych. Żeby sprawdzić, czy on istnieje, to odwołamy się do tego w ten sposób.
Czyli jeżeli nie ma wartości null albo w zasadzie tutaj zaprzeczamy,
czyli jeżeli takiego URL-a nie ma, to chcemy go stworzyć. A jeżeli jest, to chcemy go po prostu odesłać.
W jaki sposób możemy to zrobić?
Otóż wywołując nasz callback, czyli całą tę funkcję, jako error przekażemy null, bo nie było błędu, a jako drugi
parametr chcemy się odwołać do tego obiektu URL, który został pobrany z bazy. My tam jeszcze żadnego nie
mamy, zaraz go dodamy. Ale on będzie miał taką właściwość jak short, czyli skrócony adres. Oznacza to tylko
tyle, że short to może być na przykład coś takiego - ax, coś takiego - i będziemy pod to chcieli przejść. To chcemy
odesłać.
Ale chcę to połączyć jeszcze z WEBSITE_URL, czyli z tym, co mamy tutaj. Bo chciałbym, żebyśmy za chwilę
mogli przejść pod taki adres.
Coś w tym stylu. I żeby nas przekierowywało do tego oryginalnego URL.
Czyli chcę WEBSITE_URL w tym miejscu połączyć plus url.short. To za chwilę będzie istnieć i wtedy
dopiero zrobi się jasne. Tutaj był ukośnik,
więc tutaj go nie dodaję. To zostanie przekazane do call back, czyli tutaj pod short i json-em odeślemy to do siebie
pod tym właśnie short. Tutaj będzie pełny URL.
Zaraz będzie to jasne, natomiast ważniejsza rzecz jest tutaj.
Czyli jeżeli takiego URL nie ma, ktoś tutaj wpisał http://eduweb.pl, chcemy go utworzyć, pojawimy się w tym
miejscu.
Jak zatem to zrobić?
Otóż będę chciał wygenerować pięcioznakowy, losowy string i żeby to zrobić, znowu potrzebujemy jakiegoś
modułu. Taki moduł, który ja znalazłem, nazywa się Random string.
No i spokojnie można znowu w Google wpisać.
Weźmiemy pierwszy, który tutaj się znajduje.
Zobaczmy, jak on wygląda. Wygląda w porządku, więc po prostu go zainstalujemy.
Jak zatem widzisz, npm pozwala nam myśleć nad tym, jak chcemy stworzyć naszą aplikację, czyli krok po
kroku czego potrzebujemy, np. skracacz czy generator w tym przypadku takich losowych znaków, a nie musimy
myśleć, jak je wygenerować. Zainstalowałem go sobie. Z powrotem uruchamiam serwer.
Ok. Teraz zrobimy jego require na samej górze - tutaj.
W ten sposób - require(randomstring).
Tak to wyglądało.
Upewnijmy się. Dokładnie. I teraz z niego będziemy mogli skorzystać.
Czyli generując nowy taki URL,
będę chciał sobie na początku utworzyć zmienną short i odwołamy się do tego random string, który dopiero
co zaimportowałem i do metody generate.
Na stronie widzieliśmy, że taka jest i podaję ilość znaków, jakie chcę mieć w takim ciągu. Powiedzmy, że
wystarczy nam pięć i teraz utworzymy sobie z tego modelu, który mamy u góry,
nowy model, który będzie można zapisać w bazie danych. Więc napisze newURL i new URL. To ci w lekcji poprzedniej
pokazywałem. I teraz tworzymy nowy taki model zgodnie ze schematem.
Czyli ma mieć short i ma mieć pełny URL. Pełny URL
tutaj mamy pod adresem. Dokładnie tutaj. Pod value. Więc mogę napisać url: value, a tutaj napiszemy
short równa się short,
czyli ten, co przed chwilą został wygenerowany. I teraz będziemy chcieli go zapisać. NewURL.save - to
również z lekcji poprzedniej już znasz. MongoDB nam zwróci tutaj błąd, jeżeli był.
Jeżeli nie, to nowo zapisany obiekt URL w taki sposób.
Więc jeżeli się okaże, że był błąd, to chcemy ten błąd wywołać z naszym call backiem, czyli error tutaj i zróbmy
return - od razu to się zakończy.
Natomiast jeżeli nie było błędu, to wykonamy sobie nasz callback.
Wpiszemy null i dokładnie to samo, co mieliśmy tutaj pod spodem, mogę to skopiować.
Więc mam nadzieję, że to rozumiesz. Coś mamy jakiś błąd tutaj, nie postawiłem przecinka. Ok.
Jeżeli zatem uda nam się utworzyć taki nowy URL, zapisać go w bazie danych MongoDB, to on zostanie
zwrócony jako taki właśnie dokument z MongoDB i będziemy chcieli wywołać nasz callback, czyli tę funkcję jako
short, przekazując cały adres. A ten url.short będzie w nim zapisany.
Mógłbym tutaj napisać również samo short, bo mamy tutaj dostęp do tej zmiennej, ale w tym przypadku nie
ma to znaczenia. Odwołamy się do obiektu zwróconego z MongoDB.
Teraz nam to już powinno działać, więc zobaczmy, jak to będzie wyglądać.
Przejdziemy tutaj i spróbujemy zrobić taki URL dla eduweb.pl. Jeszcze tutaj tylko chciałbym odświeżyć i zobaczmy,
czy jakakolwiek kolekcja urls się utworzyła.
Nie. Ja jej tutaj ręcznie nie będę tworzył. Odświeżam. Ok.
Pojawił się błąd w 30 linijce, w API.
To dlatego, że tutaj zmieniłem to wcześniej na value. Zapisujemy. Wyczyszczę sobie tutaj te logi. Przejdziemy raz jeszcze
i okazuje się, że wszystko jest Ok. Udało się.
Mamy json error: false i short.
Jest to właśnie to website URL. I do tego dodany ten pięcioznakowy random string, który
wygenerowaliśmy.
A tutaj jeżeli odświeżę, to zobaczysz, że Mongoose utworzył dla nas kolekcję, którą nazwał urls automatycznie
i jeden taki dokument tam się będzie znajdował.
On wygląda w ten sposób. Nasze ID, które tutaj jest, dla nas w ogóle nie jest potrzebne.
Nas interesuje short oraz URL oryginalny.
No i teraz na bazie tego, co mamy tutaj, będziemy sobie mogli zrobić przekierowanie. Bo to również jest istotne,
o tym nie wspominałem, ale chciałbym teraz móc przejść pod ten adres, czyli wrzucić go tutaj.
I żeby mnie przekierowało do eduweb.pl.
Zauważ, że teraz to nie działa, ale przejdziemy sobie tutaj do index i utworzymy sobie tutaj na górze nową ścieżkę
app.get.
Nie będzie to już api, ale po prostu short, czyli chcę zrobić tutaj taki parametr. I teraz wewnątrz będę
chciał się odwołać do naszego api i do metody find, którą za moment stworzymy, przekazując jej req.params.short,
czyli dokładnie ten fragment, np. właśnie to. Przekażemy sobie to do tej metody find i chcemy wywołać
funkcję, kiedy nam to znajdzie lub nie.
Jeżeli będzie błąd, to chcę odesłać status 404 i taki tekst:
Not found.
Natomiast w przeciwnym wypadku chcemy skorzystać z res.redirect i przekierować do url, czyli np.
do eduweb.pl
Teraz pozostało nam jedynie stworzyć w naszym api funkcję find. Dlatego przejdziemy tutaj. Teraz gotowy
kod wkleję.
Metodę nazwałem findURL, więc chcę ją tutaj na samym dole jeszcze wyeksportować.
Find.
Ok, teraz już możemy z niej korzystać.
Ona jest prosta. Odwołujemy się tak jak lekcji poprzedniej pokazywałem do URL, czyli do tego modelu, i mówimy
findOne, przekazując mu short równa się short. Czyli w bazie danych
wiemy, że np. short: prI4O
mamy, więc jeżeli sobie go tutaj przekażemy, mamy go w tym miejscu. Stąd zostanie przekazany do naszej
metody find tutaj.
No więc mamy go pod short. Spróbujemy w bazie danych wyszukać, czy mamy jakiś obiekt, który ma właśnie short
równy temu, co zostało tutaj przekazane.
Jeżeli tak, zauważ, ta funkcja tak czy siak się wykona. Jeżeli będzie błąd lub będziemy mieli null, czyli
on nie zostanie znaleziony, to chcę zwrócić
dla naszego callbacka nowy obiekt błędu. Czyli w tym miejscu będziemy mieli pod error to, co tam zwrócę.
I wtedy wykona się ta linijka. Natomiast w przeciwnym wypadku chcę wywołać callback z wartością null i
przekazać url.url. Czyli pod url będzie taki zwrócony z bazy dany obiekt i on będzie miał właściwość
url równą http://eduweb.pl.
Więc to chcę sobie tutaj przekazać do naszego callbacka. I w naszym callbacku znajdzie się to tutaj.
Dlatego będziemy mogli zrobić res.redirect, a tu będzie http://eduweb.pl
Mam nadzieję, że jest to teraz zrozumiałe. Dlatego spróbujmy. Przejdźmy sobie pod ten adres. Ok. Api find is not
a function.
Przejdźmy do api - co zrobiłem źle? Napisałem tutaj findURL, a metoda nazywa się findURL, czyli powinno
być w porządku.
To wyeksportowałem.
Ok.
Teraz działa, coś prawdopodobnie się nie odświeżyło. Czyli nasz URL shortener
tak naprawdę już działa. I teraz spróbujmy sobie jeszcze inne URL-e skrócić. Może włączę Postmana i będąc tutaj,
spróbujemy wysłać zapytanie get pod api/shorten. I wiemy, że chcemy tutaj przekazać sobie jakiś URL.
Powiedzmy, że tym razem będzie to do bloga, czy napiszemy http://blog.eduweb.pl.
Mam nadzieję, że zaczynasz zauważać, jak to działa. Mógłbyś teraz w jQuery lub w jakiejkolwiek innej technologii,
np. w aplikacji mobilnej, napisać sobie taki programik, gdzie ktoś mógłby wpisać po prostu adres URL
i kiedy kliknąłby skróć,
no to ty po prostu wysłałbyś zapytanie get standardowo pod taki adres i z powrotem otrzymał byś json-a -
zobaczmy - w którym miałbyś error: false, jeżeli nie było błędu, a pod short miałbyś cały ten adres i mógłbyś
go komuś wyświetlić po prostu poprzez .short. I po kliknięciu na ten adres - my sobie go teraz skopiujemy -
powinno nas przekierowywać za każdym razem na blog.eduweb.pl
Więc wróćmy do Canary. Wklejam taki adres i rzeczywiście blog.eduweb.pl jest poprawnie wyświetlany, więc
wszystko działa.
A co stałoby się, gdyby ktoś jeszcze raz chciał skrócić taki adres? Czyli ktoś inny przyjdzie i chciał
sobie skrócić blog.eduweb.pl
i wyśle, to zauważ, że dokładnie to samo zostanie odesłane. Za każdym razem będziemy mieli taki sam string.
Czyli zadbaliśmy o to, aby nie dodawać do bazy danych MongoDB kolejnych wpisów, które kierują na dokładnie
ten sam adres URL.
Mam nadzieję, że wszystko dobrze zrozumiałeś.
Na koniec pokażę ci jeszcze tylko jeden trik z plikiem hosts na Macu. Tutaj przejdziemy do terminala. Zatrzymam
sobie ten serwer, wyczyszczę ekran i teraz wpiszemy sobie sudo nano, aby edytorem Nano otworzyć plik, który znajduje się
w /etc/hosts/
W Windowsie znajdziesz ten plik pod ścieżką, która się teraz wyświetliła na dole. Natomiast na Macu
w ten sposób tutaj przechodzimy.
I tutaj możemy sobie hosty definiować. To, co ja będę chciał zrobić, to sprawić, aby pod adres 127.0.0.1,
czyli jest nasz localhost, aby pod ten adres kierowała domena edu.web, która tak naprawdę nie
istnieje.
Teraz to zapiszę, wciskając Ctrl+O, Enter i Ctrl+X.
I teraz jeżeli zmienimy sobie w naszej aplikacji, będąc tutaj, ten adres, który jest w tym miejscu na edu.web,
to wszystko będzie w porządku. Jeszcze oprócz tego, że port mieliśmy tutaj 8080.
Muszę ten port zmienić, bo teraz będą linki skrócone zwracane w ten sposób.
Muszę to zmienić i uruchomić nasz serwer na porcie 80. Aby to zrobić, musisz mieć uprawnienia administratora.
Więc jeżeli teraz będę chciał nodemonem uruchomić to w ten sposób, czyli nodemon index. Ok.
To nam się nie uda, bo nie mamy odpowiednich uprawnień.
Dlatego na Macu mogę wpisać sudo nodemon index, a w Windowsie musisz uruchomić wiersz poleceń jako administrator
i dopiero wpisać nodemon index - bez sudo.
Zobaczmy.
Teraz się udało to uruchomić i nasz serwer uruchomi się pod takim właśnie adresem.
Już nie musimy podawać portu, bo port 80 jest zakładany domyślnie. Czyli jeżeli przeglądarka wysyła
zapytanie pod taki adres, to wyśle go właśnie na porcie 80.
Zauważ, że nasza strona działa, nie definiowaliśmy tej pierwszej, ogólnej ścieżki, dlatego tutaj nic nie ma.
Ale jeżeli teraz pod ten adres sobie przejdziemy i api/shorten, i tutaj podam URL bloga eduweb.pl.
Wciskam Enter.
Zauważ, że zostanie dla nas zwrócony taki oto adres. Jeszcze popełniłem jeden błąd, bo nie dodałem tutaj
na końcu /.
Zróbmy to raz jeszcze. Ok. Teraz jest w porządku. I po co ci to pokazałem?
Otóż właśnie po to, żebyś zobaczył, że przy localhost nie wyglądało to fajnie, ale jeżeli będziesz miał kupioną
domenę jakąś krótką, to świetnie wyglądają takie URL shortenery. W tym przypadku jeżeli sobie przejdę
pod taki adres, to przekieruje nas na bloga eduweb.pl.
Wszystko działa poprawnie. Natomiast tak naprawdę oszukaliśmy sobie to trochę, robiąc taką oto ścieżkę.
Natomiast ja tutaj wrócę do tej poprzedniej wersji i tak ci to zostawię w plikach źródłowych. Czyli tutaj
nie będziemy na porcie 80, ale na 8080.
Jak zatem zobaczyłeś, stworzenie takiego url shortenera jest całkiem proste.
Oczywiście on nie bierze pod uwagę jak zwykle wszystkich tzw. edge case'ów, gdzie coś mogłoby pójść nie tak.
Dlatego gdybyś chciał go do produkcji wdrożyć, trochę jeszcze nad nim należałoby popracować.
Natomiast jeżeli w Google sobie wpiszesz node.js url shortener, to na GitHubie znajdziesz mnóstwo przykładów, jak zrobili
to inni.