Najważniejsze zagadnienia, które musisz znać
5 godz. 53 min · JavaScript · Full-stack i Programowanie
Adam GospodarczykPrzesyłanie oraz transformacja danych to jeden z najważniejszych elementów działania każdej aplikacji. Dobre zrozumienie tego w jaki sposób odbywa się ten proces, daje równocześnie lepsze zrozumienie całej struktury oraz podejmowania decyzji projektowych. W tym kursie znajdziesz lekcje, które pozwolą Ci uporządkować wiedzę na temat protokołu HTTP oraz formatów wymiany danych.
REST oraz GraphQL to nadal nieodłączone zagadnienia tematu wymiany informacji w kontekście aplikacji webowych. Pomimo tego, że ich koncepcje zwykle są bardzo dobrze opisane w różnych źródłach, tak ich wykorzystanie "na produkcji" potrafi sprawić problemy. W szczególności gdy weźmiemy pod uwagę, wyjątki oraz fakt, że nie każda aplikacja będzie wymagać implementacji REST czy GraphQL w 100%. W tym kursie znajdziesz wiele praktycznych wskazówek związanych z pracą z REST API oraz wprowadzenie do pracy z GraphQL.
Niektóre błędy w aplikacji są bardzo pożądane, w szczególności gdy jasno informują użytkownika o tym, co się wydarzyło oraz o tym, co może z tym zrobić. Pomimo tego, że w wielu przypadkach opracowanie komunikatów leży w rękach osoby odpowiedzialnej za copywriting (i/lub ux writing), tak sama implementacja tych komunikatów odbywa się po stronie kodu. Nie rzadko okazuje się, że poprawna i skuteczna walidacja danych oraz obsługa błędów nie jest oczywista w "produkcyjnych" sytuacjach. W tym kursie znajdziesz najczęściej spotykane problemy oraz sposoby ich rozwiązania.
Bazy danych są praktycznie nieodłączną częścią każdej aplikacji. W roli full-stacka prędzej czy później przyjdzie Ci z nimi pracować a nie rzadko nawet projektować oraz rozbudowywać ich struktury. W tym kursie znajdziesz informacje o bazach danych, które pozwolą Ci je zrozumieć oraz od razu poznać użyteczne techniki, które pomogą Ci w pracy z nimi, zarówno na produkcji jak i w środowisku lokalnym czy testowym.
Nie wszystkie informacje w aplikacji są publiczne. Niektóre wprost nie mogą takie być. Z tego powodu niezbędne są sposoby na to aby poznać a potem weryfikować tożsamość użytkownika, by na jej podstawie przydzielać mu dostęp wyłącznie do zasobów, do których odczytywania posiada uprawnienia. Istnieje wiele technik, które umożliwiają zarządzanie dostępem do danych i w tym kursie poznasz najważniejsze z nich. Dowiesz się nie tylko w jaki sposób zabezpieczać dane ale poznasz też najpopularniejsze sposoby na to aby te zabezpieczenia łamać i obchodzić. Mając świadomość takiej możliwości, będziesz w stanie lepiej podejmować decyzje o tym jak projektować dostęp do informacji.
Istnieją problemy charakterystyczne dla niemal każdej aplikacji. W związku z ich powszechnością, istnieje też szereg rozwiązań lub sposobów na to, aby możliwie zredukować ich następstwa. Na przestrzeni lekcji tego kursu zobaczysz wiele przykładów, które pomogą Ci w codziennej pracy a niekiedy nawet, pozwolą uniknąć błędów, których konsekwencje nie zawsze występują natychmiast.
Kurs powstał z myślą o osobach, które chcą rozwijać się w roli full-stack web developera / developerki, przeprowadzając przez najważniejsze zagadnienia z obszaru wymiany, transformacji oraz przechowywania informacji w aplikacji oraz pomiędzy aplikacjami. Jeżeli potrzebujesz zobaczyć szeroką perspektywę tego, w jaki sposób dane przepływają pomiędzy różnymi częściami aplikacji, lub ugruntować swoją wiedzę na ten temat, to ten kurs jest miejscem, którego szukasz.
Na ten moment już dość dobrze orientujesz się w tym, w jaki sposób aplikacja
komunikuje się ze światem i komunikuje się pomiędzy różnymi swoimi warstwami, czyli
inaczej mówiąc jak przepływają wewnątrz niej informacje.
Jednocześnie musimy nieco pogłębić ten temat, aczkolwiek i tak będziemy dotykać
go dość powierzchownie ze względu na to, że temat np.
protokołu HTTP jest bardzo obszerny.
Dla mnie jednak istotne jest to, aby były
dla Ciebie jasne jego możliwości oraz też praktyczne wykorzystanie.
No bo przykładowo zapewne kojarzysz już doskonale metody GET oraz POST.
Natomiast musisz wiedzieć, że istnieją jeszcze metody put oraz direct.
Teraz co ciekawe, to nie jest pełna lista dostępnych metod w protokole HTTP.
Przykładowo jeżeli przejdziemy teraz na stronę MDM to zobaczymy, że mamy tutaj
jeszcze metody Head, Connect, Options czy Trace.
Oczywiście warto coś na ich temat wiedzieć, natomiast jednocześnie też
musisz mieć świadomość tego, że większość API, z którymi przyjdzie Ci pracować mogą
wykorzystywać wyłącznie metody GET oraz POST.
W niektórych przypadkach będą pojawiać się metody PUT oraz direct.
Tak jak mówiłem w jednej z poprzednich lekcji, te metody służą do tego, aby
rozluźnić akcję wykonywaną na danym end poincie.
Dzięki temu np.
możemy metodą GET na endpoint users pobrać
informacje o użytkownikach metodą POST, utworzyć nowego metodę PUT, zaktualizować
cały obiekt, a metodą patch tylko jego niektóre elementy.
No i też ostatecznie metodą możemy je usunąć.
Jednak od teraz Twoje spojrzenie na te metody powinno się delikatnie zmienić.
Mianowicie przyjdzie Ci nie tylko z nimi pracować, ale również je projektować.
Oznacza to, że to nie jest tylko tak, że stworzyć sobie API, które obsługuje
wszystkie metody i wszystko będzie w porządku.
Natomiast w praktyce musisz jeszcze zadbać
o poprawne obsłużenie tych metod po stronie backendu.
Z tego powodu jest całkiem mądre to, aby
wybierać tylko te metody, z którymi faktycznie przyjdzie Ci pracować.
Przykładowo, nic nie stoi na przeszkodzie,
aby wykorzystać tylko metodę POST, a metody put oraz patch całkowicie pominąć.
Naturalnie dobrze byłoby zaimplementować
je wszystkie, ale po prostu w niektórych przypadkach nie ma to znaczenia.
Zatem na ich temat musisz wiedzieć przede
wszystkim tyle, że metoda GET pobiera informacje, metoda post zapisuje je.
Metoda PUT umożliwia aktualizację istniejącego rekordu, ale w postaci
przesłania całego obiektu oraz jego podmianę.
A metoda patch robi zasadniczo to samo, tylko np.
z pojedynczymi bądź przejściowymi właściwościami danego obiektu.
No i ostatecznie metoda init służy usuwaniu.
Aczkolwiek tak jak Ci powiedziałem,
niekoniecznie rekord musi zostać usunięty całkowicie z bazy, ale może zostać np.
zarchiwizowane bądź też anonimizacji.
Czyli inaczej mówiąc tak jakby usunięte,
ale po prostu pozostanie po nim jakiś ślad w naszej bazie.
No i teraz oprócz samych metod mamy jeszcze nagłówki, których rola polega na
doprecyzowanie wymiany informacji pomiędzy serwerem a klientem.
Zatem przede wszystkim klient może
określić jakiego typu informacje chce pobrać z serwera.
Przykładowo, jeżeli wyśle zapytanie o application slash Jameson, czyli po prostu
odpowiedź w formacie Jameson, no to serwer powinien być gotowy na to, aby to zrobić.
Jednocześnie też to, czy ten nagłówek zostanie w ogóle respektowany, zależy w
dużym stopniu od tego, jak implementujemy endpoint po stronie serwera.
Z tego powodu w większości przypadków raczej nie zwracamy uwagi na ten nagłówek.
Aczkolwiek niektóre API wymagają tego,
abyśmy doprecyzowanie i rodzaj danych, które chcemy otrzymać z danego pointą.
Kolejny nagłówek to autoryzację, czyli na
tyle istotny temat, że będziemy do niego jeszcze wracać kilkukrotnie.
Służy on do uwierzytelnienia połączenia z pomocą np.
klucza API.
Aczkolwiek zamiast takich nagłówków możemy też wykorzystywać tokeny JW, które nie
przesyłane są w formie nagłówka, ale dołączane są do połączenia w formie
ciasteczka, ale o specjalnym typie tak zwanym HTTP only.
Oznacza to, że takie ciasteczko jest dołączone do połączenia, ale jednocześnie
nie ma do niego dostępu z poziomu kodu JavaScript.
Na koniec dnia rezultat jest taki, że nasze połączenie jest uwierzytelnione, ale
po prostu nie musimy przejmować się dodawaniem kolejnych nagłówków.
Następnie content określa dane, które są przesłane razem z zapytaniem.
Oznacza to, że na tej podstawie jesteśmy w stanie doprecyzować, że np.
dane połączenie powinno zwrócić obrazek bądź plik tekstowy czy np.
HTML.
Z tego powodu takie nagłówki wchodzą w skład szeroko pojętego security, czyli po
prostu bezpieczeństwa połączenia, o czym za chwilę sobie jeszcze powiemy.
Następnie mamy samo Kuki, które właśnie przesyłane jest w formie nagłówka.
Aczkolwiek tak jak powiedziałem, w przypadku ciasteczek HTTP
nie musimy albo nawet nie możemy z poziomu JavaScriptu decydować o ich zawartości.
Takie ciasteczka definiowane są na
poziomie serwera i to przez niego też zwracane są z odpowiedzią na zapytanie i
też dołączane automatycznie przez przeglądarkę do kolejnych.
Następnie na liście mamy pamięć podręczną.
I tutaj również nagłówki odgrywają ogromną
rolę zarówno po stronie serwera, jak i klienta.
Ze względu na to, że różne mechanizmy dotyczące pamięci podręcznej, czy też
potem również kompresji wpływają na sposób przesyłania danych i też np.
przechowywania ich po swojej przeglądarki lub też kompresowane po stronie serwera.
I ostatnim wątkiem, który ja mam tutaj na liście jest szeroko pojęte security, które
również poniekąd wiąże się ze wcześniejszymi nagłówkami.
Natomiast w praktyce tych nagłówków dotyczących security i na przykład tego,
że serwer może odrzucać połączenia, które nie pasują do zdefiniowanych reguł.
Oznacza to, że przykładowo nagłówki, które
są przekazywane przez klienta muszą być dopasowane do wymagań serwera.
W przeciwnym razie połączenie zostanie odrzucone.
Jak widzisz, temat nagłówków jest czymś,
czego absolutnie nie powinniśmy ignorować, ale jednocześnie jest to temat na tyle
obszerny, że momentami trudno to wszystko ogarnąć.
Z tego powodu większość tych nagłówków
ustawiana jest automatycznie lub automatycznie na podstawie
wykorzystywanych przez nas narzędzi, takich jak na przykład PHP czy akcja.
Ale też po stronie serwera możemy skonfigurować tzw.
helmet, którego odmiany funkcjonują np.
w Next, że jest chociażby Neostrada.
Dzięki temu po prostu podłączamy sobie
odpowiedni zestaw, który ewentualnie możemy jakoś dostosować
do swoich potrzeb, ale jednocześnie zmniejszamy ryzyko, że np.
zapomnimy ustawić jakiegoś nagłówka, który
powinien być zdefiniowane właśnie z punktu widzenia bezpieczeństwa.
Zobaczmy więc, jak niektóre elementy dotyczące nagłówków wyglądają w praktyce.
Mam tutaj przygotowany prosty flagę,
którego zadaniem jest pobranie informacji z danego endpoint, a następnie
wyświetlenie prostego loga z nagłówkami, które zostały zwrócone z serwera.
I swoją drogą, jeżeli interesuje Cię ten specyficzny zapis, to jest to nic innego
jak określenie kolorów zakodowanego komunikatu.
Gdzie po przecinku określamy styl CSS dla
elementów, które są poprzedzone znakiem procenta oraz C.
Dzięki temu ten pierwszy kolor będzie
zastosowany dla pierwszego fragmentu tekstu.
A potem mamy drugie oznaczenie, które zostanie powiązane z drugim kolorem.
W każdym razie, jeżeli udostępnimy sobie
serwer deweloperski, to zobaczymy, że w konsoli powinien zostać wyświetlony
nagłówek Application Jamesa i dokładnie też w takim formacie.
Jeżeli przejrzymy sobie teraz zakładkę Content, powinna trafić do nas odpowiedź.
Tak dokładnie się stało i mamy tutaj naszych użytkowników.
Jeżeli jednak tutaj przekażemy nowy
nagłówek Content type ustawiony na text xml, no to w tej sytuacji, jeżeli ponownie
podejmiemy konsolę, to przede wszystkim otrzymamy informację o
tym, że w odpowiedzi otrzymaliśmy nagłówek text xml.
A. Jeżeli chodzi o zawartość odpowiedzi, to w
tym przypadku rzeczywiście mamy strukturę XML.
Jest to bardzo proste, ale doskonały przykład tego, w jaki sposób możemy
kontrolować komunikację pomiędzy klientem a serwerem.
Oczywiście to wszystko w tym momencie jest bardzo proste.
Natomiast nawet tylko na tym przykładzie.
Mamy tutaj token, który identyfikuje
naszego użytkownika i też daje dostęp do różnych zasobów np.
na podstawie tego jaką rolę posiada użytkownik w naszym serwisie lub też np.
czy ma wykupioną i aktywną subskrypcję.
To wszystko może być określane wyłącznie za pomocą tego jednego nagłówka.
Oczywiście jest to tylko pewien sygnał dla aplikacji działającej po stronie backendu.
Co dokładnie ma zrobić?
Do czego dostęp i w jakiej formie?
No i tak samo jeżeli chodzi o content, również jesteśmy w stanie kontrolować to,
jak wygląda odpowiedź, która bez wątpienia zasadniczo zmieni to, w jaki sposób możemy
wchodzić w interakcję z danymi po stronie klienta.
Jednocześnie też zwróćcie uwagę, że jeżeli
tutaj zrobilibyśmy jakiś zupełnie inny content, no to zachowanie naszej aplikacji
mogłoby odbywać się tutaj na różne sposoby.
W moim przypadku otrzymamy tutaj odpowiedź
ze względu na to, że jest to domyślny schemat odpowiedzi.
Jednak nic nie stoi na przeszkodzie, aby w takiej sytuacji poinformować użytkownika o
tym, że niestety nie obsługujemy wybranego formatu danych i musi go zmienić.
Oczywiście w moim przypadku w związku z tym, że komunikujemy się na łeb w
aplikacji maile, to tak naprawdę sposób zwrócenia odpowiedzi sprowadził się
wyłącznie do tego, aby zweryfikować nagłówek i jego zawartość.
I w momencie, gdy jest ustawiony na XML, zwracamy właśnie taką treść.
W przeciwnym razie mamy tutaj do czynienia z odpowiedzią.
Akurat w tym przypadku było to stosunkowo
proste, jednak to samo będzie działo się po stronie Twojego backendu.
Po prostu analogicznie, tak jak w tym przypadku, odczytujemy nagłówek, który
został przesłany wraz z zapytaniem, a następnie na podstawie jego zawartości
określamy to, w jaki sposób będzie wyglądać odpowiedź na to pytanie.
No bo teraz przykładowo jeżeli przejdziemy
do naszej backend owej aplikacji, gdzie mamy zdefiniowany kontroler, to tutaj
również moglibyśmy odwołać się do obiektu, czyli tego zawierającego zapytanie.
I właśnie jeżeli tutaj uruchomimy sobie debugger, to będziemy.
Podejrzeć zawartość tego obiektu.
No bo spójrz, jeżeli teraz uruchomię
localhost 3000, to aplikacja zatrzyma się dokładnie w tym miejscu.
I widzimy tutaj dokładnie nagłówki oraz
ich wartości, które zostały przesłane razem z tym zapytaniem.
To właśnie te wartości mogą, ale wcale nie
muszą być przez nas akceptowane i respektowane.
Do tego, aby przygotować odpowiedź dla klienta.
Oczywiście to, które z nich będziemy
obsługiwać, a które nie, zależy wyłącznie od naszej aplikacji i naszych potrzeb lub
też od potrzeb naszych klientów, którzy mogą korzystać z naszego API.
I teraz oczywiście to w jaki sposób będziemy w stanie odczytywać same nagłówki
będzie różnić się od stacku technologicznego, z którego korzystamy.
Natomiast chociażby w przypadku, że jest.
Wystarczy odwołać się do obiektu żądania, czyli request, a następnie do właściwości
head i tutaj do klucza powiązanego z konkretnym nagłówkiem.
Zatem jeżeli teraz ponownie uruchomię naszą aplikację, to mamy tutaj też
potwierdzenie, że wartość nagłówka host została ustawiona na localhost 3000.
To wszystko się zgadza i nawet na tej
podstawie jesteśmy w stanie przefiltrować to, czy np.
połączenie wykonywane jest z konkretnej
domeny i czy nie pochodzi z jakiegoś nieznanego źródła.
Ostatecznie jednak, tak jak powiedziałem, bardzo dobrym pomysłem i wręcz wymaganiem
jest wykorzystanie helmet, czyli specjalnej paczki, która w przypadku MSG
jest działa tak, że po prostu importujemy ją do naszej aplikacji, a następnie
podłączamy na etapie tworzenia samej aplikacji.
No i tutaj oczywiście chodzi nam o schemat, czyli funkcję, którą chcemy
wykonać, która przygotuje dla nas odpowiednie nagłówki i też zestaw
middleware, które zadbają o automatyczne dodanie szeregu wymaganych nagłówków.
Oczywiście warto mieć na uwadze fakt, że
niektóre te ustawienia będą zbyt wymagające co do naszej aplikacji i po
prostu będziemy musieli nadpisać pewne właściwości w obiekcie konfiguracyjnym, po
to, aby niektóre zabezpieczenia dostosować do naszych potrzeb lub też ewentualnie z
pełną świadomością konsekwencji je po prostu wyłączyć.
Analogicznie też całkiem dobrym przykładem podobnego narzędzia, które w tym przypadku
ułatwia nam przesyłanie plików wewnątrz aplikacji, jest tzw.
Mulder.
Dzięki niemu jesteśmy w stanie przetwarzać upload plików i odpowiednio np.
weryfikować ich MIME oraz poszczególne
właściwości, tak aby upewnić się, że nie mamy tutaj do czynienia z jakimiś
złośliwymi plikami lub też po prostu plikami, które z jakiegoś powodu nie
pasują do wymaganej przez nas specyfikacji.
Zatem szczerze mówiąc, to co warto zapamiętać z tej lekcji to to, że pomimo
tego, że istnieje wiele różnych metod i wiele różnych nagłówków, warto wybierać
tylko te, które faktycznie okazują się przydatne w Twojej aplikacji.
Jednocześnie też, jeżeli chodzi o nagłówki, warto zadbać o to, aby za pomocą
narzędzi takich jak Helmet po prostu zadbać o elementy takie jak security.
I to bywa szczególnie przydatne w
momencie, gdy dopiero zaczynamy naszą przygodę jako full stack i też nie mamy
pełnej wiedzy na temat wszystkich nagłówków.
Ja sam nie mogę powiedzieć, że wiem wszystko na temat wszystkich, ale mniej
więcej orientuję się w pracy z tymi najczęściej spotykanymi.
Jednocześnie miej na uwadze fakt, że to Ty odpowiadasz za to, jak wygląda komunikacja
w Twojej aplikacji pomiędzy światem zewnętrznym oraz jej różnymi częściami.
W związku z tym nie tylko musisz zadbać o
to, aby ta komunikacja była poprawnie ułożona, ale też poprawnie przebiegała.
Oznacza to, że jeżeli przykładowo zdecydujesz się na zastosowanie metody
patch, no to Twoja rola polega również na tym, aby właściwie ją obsłużyć.
Miej to na uwadze i nie chcę Cię w ten
sposób absolutnie zniechęcać, tylko wręcz przeciwnie.
Zachęcam Cię do tego, aby poznawać te
wszystkie metody i przykłady ich zastosowania oraz tego, kiedy warto się na
nie zdecydować, a w jakich przypadkach zupełnie nie ma to sensu.
Teraz dzięki za uwagę i do usłyszenia za chwilę.