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.
W momencie, gdy stajesz się pustakiem, Twoje spojrzenie na przepływ informacji
wewnątrz aplikacji drastycznie się zmienia.
Wynika to z faktu, że przestajesz już być
wyłącznie użytkownikiem danego API, ale również to na Tobie spoczywa
odpowiedzialność, aby je tworzyć i rozwijać.
Uwzględniając w tym wszystkim różne
zawiłości oraz chociażby elastyczność i podatność na dalszy rozwój.
Zacznijmy od tego, że pierwszym tematem, który z pewnością będzie zajmować Ci
bardzo dużo uwagi jest autoryzacja oraz uwierzytelnienie użytkowników.
Dobra wiadomość jest taka, że w tym temacie już wiele zostało wymyślone i masz
do dyspozycji mnóstwo narzędzi, które są w stanie Ci w tym pomóc.
Jednocześnie gdy zaczniesz zgłębiać ten
temat, to okaże się, że jest tam wiele różnych detali, o których publicznie się
nie mówi i które mogą sprawić trochę problemu.
Ważniejsze jest jednak to, aby było dla Ciebie jasne, że istnieją takie sposoby,
że masz do dyspozycji mechanizmy takie jak zabezpieczenie API z pomocą klucza API,
które udostępniasz użytkownikowi i na tej podstawie uwierzytelnianie połączenie.
Drugim zdecydowanie bardziej złożonym
mechanizmem są widzenia użytkownika, jak i też samej implementacji jest OLAF 2.0.
Jednocześnie też trzeba przyznać, że w porównaniu do wykorzystania klucze mówimy
tutaj o nieco bardziej bezpiecznym sposobie.
Następnie mamy Jameson Web Token, czyli
obecnie jeden z najpopularniejszych sposobów na uwierzytelnienie użytkownika
oraz oczywiście sesje, które są wykorzystywane w klasycznych aplikacjach.
Raczej coraz rzadziej spotykane, ale jednocześnie w wielu miejscach.
Czytałem, że wielokrotnie w miejscach, w których wykorzystujemy Jameson Web Token
moglibyśmy skorzystać z sesji i tak naprawdę byłoby to lepsze rozwiązanie.
Nie mnie to oceniać i powiem tylko, że
warto znać te wszystkie mechanizmy i ewentualnie w zależności od sytuacji
sięgać po ten, który najlepiej się sprawdzi.
Kolejnym wątkiem, o której musisz wiedzieć jest szeroko pojęte security.
I tutaj mam na myśli nie tylko
zabezpieczenie naszego API poprzez odpowiednią autoryzację i uwierzytelnienie
użytkownika, ale również przykłady, o których mówiłem w poprzednich lekcjach,
dotyczących chociażby licznych błędów, jak nie zabezpieczenie
wybranych endpoint, bądź też zrobienie tego w sposób, który i tak umożliwia
użytkownikowi dostęp do danych, do których nie powinien mieć dostępu.
Co ciekawe, doskonałym przykładem może być
nawet prosty endpoint odpowiadający za pobranie listy wybranych rekordów.
Przykładowo tutaj mamy dokumentację f
table i akurat w tym przypadku pobranie wszystkich rekordów z wybranej bazy jest
dopuszczalne, ponieważ zwykle wykorzystujemy ją na nasze potrzeby.
Ale w momencie, gdy projektujemy API,
warto w jakiś sposób ograniczyć dostęp do zasobów danego użytkownika, aby nie doszło
do sytuacji, w której ktoś po prostu pobierze nam całą bazę danych i np.
wykorzystają do swoich potrzeb.
Oczywiście w niektórych sytuacjach może
zdarzyć się tak, że nie będziemy mieć problemu z tym, aby ktoś pobrał sobie
wszystkie informacje z naszej bazy, ale w niektórych przypadkach może okazać się to
problematyczne i warto zastanowić się, w jaki sposób możemy to ograniczyć.
Kolejny wątek, który przyjdzie Ci oglądać
z dwóch stron to filtrowanie oraz pagina sesja.
W momencie, gdy masz gotowe API i zestaw reguł pozwalających Ci na filtrowanie oraz
częściowe pobieranie rekordów, to raczej nie ma problemu z ich wykorzystaniem.
W przypadku jednak, gdy staniesz po
drugiej stronie i potrzebujesz zaimplementować te mechanizmy w taki
sposób, aby mogły się ze sobą łączyć, czyli np.
aby można było przefiltrować wyniki, posortować je w odpowiedniej kolejności, a
następnie pobrać porcjami to już zupełnie inna zabawa.
Oczywiście przez niektóre przykłady będziemy sobie przechodzić, ale np.
w sytuacji, gdy mamy do czynienia z
zaawansowanym mechanizmem wyszukiwania oraz narzędziami takimi jak Elastic,
to tutaj mówimy już o bardzo wysokim poziomie złożoności, o którym z
powodzeniem można nagrywać oddzielne kursy.
Pamiętaj jednak o tym, że w tym temacie
bardzo pomoże Ci znajomość SQL a czy innego języka bądź archiwów, które
wykorzystasz do połączenia z Twoją bazą danych.
Po prostu to Ty będziesz tutaj odpowiadać
za to, w jaki sposób będzie przygotowywane to zapytanie.
I też pamiętaj o tym, aby czasem nie
doprowadzać do sytuacji, w której po prostu z serwera pobierasz wszystkie dane
i następnie dokonujesz filtrowania po stronie klienta.
Coś takiego jest najgorszym możliwym
scenariuszem i może sprawdzić się co najwyżej w bardzo małych aplikacjach, bądź
w przypadku, gdy masz do czynienia z naprawdę małą liczbą danych, np.
bardzo ograniczoną listą tagów.
Idąc dalej, kolejnym elementem, na który trzeba zwrócić uwagę jest spójność.
Tutaj ponownie w momencie, gdy tylko korzystasz z API, tak naprawdę co najwyżej
możesz wymagać tego, aby jego twórcy dbali o strukturę end pointów oraz strukturę
odpowiedzi, tak aby można było z tym API wygodnie pracować.
W tym momencie odpowiedzialność za to spada na Ciebie i przede wszystkim musisz
mieć na uwadze fakt, że zachowanie spójności jest po prostu bardzo istotne.
Bardzo pomaga w tym temacie przynajmniej
orientowanie się w ogólnie przyjętych konwencjach i regułach i też nabywanie
doświadczenia w ich praktycznym wykorzystaniu.
Przykładowo REST API.
Mimo tego, że jest dość dobrze opisane i
są materiały, które pomogą Ci je zrozumieć.
Tak, Jednocześnie w środowisku produkcyjnym bardzo często dochodzi do
momentów, w których to trudne jest ścisłe stosowanie się do wszystkich zaleceń.
Nie zmienia to jednak faktu, że zachowanie
spójności ma nie tylko charakter teoretyczny, ale również praktyczny.
Przykładowo, będziemy przechodzić przez
przykłady przygotowywania takich globalnych funkcji odpowiedzialnych za
przygotowywanie odpowiedzi zwracanej przez nasze API.
Dzięki temu, niezależnie od tego, w którym miejscu będziemy zwracać wyniki, ta
funkcja zadba o to, aby zwracane obiekty był zbudowany tak samo i tym samym jego
wykorzystanie na froncie było łatwe, a jednocześnie, aby nie sprawiało trudności
każdorazowe zastanawianie się, w jaki sposób mamy zwrócić dane.
Kolejnym wątkiem, który trzeba mieć na uwadze jest fakt, że API, które
przygotowujesz może być zarówno publiczne, jak i wewnętrzne.
Jedno i drugie w dużej części posiada
wspólne cechy, ale w niektórych przypadkach może się różnić.
Przykładowo, jeżeli budujesz API wyłącznie na swoje potrzeby bądź też potrzeby swojej
aplikacji, to w większości przypadków elementy takie jak np.
ograniczenie liczby zapytań raczej nie stanowi tutaj problemu.
Jednocześnie w momencie, gdy udostępnia
swoje API publicznie, to musisz zadbać chociażby o to, aby umożliwić
użytkownikowi chociażby usunięcie swojego tokenu API, bądź tez zarządzenie
uprawnieniami dostępu, jakie dany klucz posiada.
I tak samo warto pamiętać o tym, że jeżeli budujesz wewnętrzne API, to musisz upewnić
się w pierwszej kolejności, że faktycznie jest ono wewnętrzne.
Nietrudno jest skonfigurować np.
engine X w taki sposób, aby przypadkowo odsłonić nasze API dla użytkowników
zewnętrznych, którzy dodatkowo nie będą potrzebowali nawet jakiegokolwiek klucza,
aby z niego korzystać i eksploatować jego możliwości.
O tym, w jaki sposób wykorzystać np.
proxy engine również będziemy rozmawiać i ostatecznie mamy jeszcze CASY, czyli
sytuację z jakiegoś powodu charakterystyczne dla Twojej aplikacji
bądź konkretnego problemu, z którym się mierzysz.
I w tej sytuacji to również Ty dbasz o to,
aby znaleźć rozwiązanie i zaimplementować je zarówno na froncie jak i na backend.
Jeżeli wydaje Ci się, że to wszystko, to na naszej liście znajdują się jeszcze
logi, czyli zasadniczo zapisywanie tego, kto, kiedy i do czego uzyskuje dostęp.
Na tej podstawie jesteś w stanie prowadzić różnego rodzaju statystyki.
W niektórych sytuacjach rozliczać użytkowników w ramach płatnego dostępu do
API, a jeszcze innym razem wyłapywać błędy bądź też nieautoryzowane próby dostępu.
Oczywiście tutaj też warto zadbać o to,
aby przeprowadzić ten proces poprawnie, ponieważ nawet w ostatnich tygodniach
słyszałem o sytuacji, w której doszło do wycieku danych i to bardzo wrażliwych,
ponieważ pomimo tego, że główna aplikacja była odpowiednio zabezpieczona, tak
jednocześnie istniał poboczny serwis właśnie odpowiedzialny za logi, do którego
trafiały pełne informacje o użytkownikach, łącznie z ich jakimiś prywatnymi
informacjami, które co gorsza nie były w żaden sposób zaszyfrowane.
No i ostatni temat to właśnie różnego
rodzaju limity, o których już zdarzyło mi się wspomnieć.
Natomiast pamiętaj o tym, że mówimy tutaj nie tylko o limitach dotyczących prostych
ograniczeń, takich jak chociażby liczba zapytań w ciągu miesiąca, ale również tzw.
limity, czyli opcja ograniczenia dostępu
do API w przypadku bardzo dużej liczby zapytań.
No i teraz jeszcze łącząc te wszystkie
wątki warto zadbać również o dokumentację naszego API.
Niezależnie od tego, czy mówimy tutaj o jego prywatnym i wewnętrznym
wykorzystaniu, czy też udostępnieniu innym użytkownikom.
No i teraz zobaczmy, jak te wszystkie
tematy, o których sobie tutaj powiedzieliśmy, sprawdzają się w praktyce.
Na przykładzie API Table, które moim zdaniem jest świetnie przygotowane.
To na co trzeba zwrócić tutaj uwagę to
fakt, że jest ono generowane konkretnie na podstawie mojego projektu i też
przykładowo wszystkich tabel, które znajdują się aktualnie w bazie danych.
Jednocześnie mam tutaj wszystkie
informacje, które mogą mnie interesować na temat właśnie ograniczeń zapytań do tego
API oraz sposobu, które mogę wykorzystać do tego, aby się z nim połączyć.
Jasno znajduje się tutaj informacja, że w
celu połączenia mogę wykorzystać nagłówek Auto Dizajn wykorzystujące mój klucz API.
I tak samo opis wszystkich dostępnych
tutaj metod wraz z przykładami zarówno zapytań, jak i odpowiedzi.
To wszystko sprawia, że korzystanie z takiej dokumentacji jest niezwykle wygodne
i też jej przygotowanie i zarządzanie również nie sprawia większego problemu.
No bo w dużym stopniu generowane jest dla nas automatycznie.
Jednocześnie zwrócić tutaj uwagę na fakt, że mamy tutaj zaimplementowane wszystkie
elementy dotyczące chociażby częściowego pobierania informacji z danego rekordu czy
też filtrowania i po wszystkie te tematy twórcy tabel musieli zadbać.
I dodatkowo tutaj do gry wchodzi również utrzymanie oraz rozwój tego API,
uwzględniające chociażby różne wersje tego API.
Co prawda akurat w przypadku EF, bo o ile mi wiadomo istnieje tylko jedna wersja
API, ale od czasu do czasu pojawiają się w nim nowe funkcje, bądź też np.
w ostatnim czasie pojawiło się ograniczenie dotyczące przechowywania.
Wewnątrz bazy tabel.
W każdym razie nie skupiajmy się tutaj na
szczegółach dotyczących samego tabel, ale na przykładach dotyczących tego nie tylko
w jaki sposób jesteś w stanie zorganizować dokumentację i też uwzględniać jakieś
konkretne szczegóły, ale też w momencie, gdy od tej pory będziesz pracować z API,
to zwracaj uwagę na to, w jaki sposób ustrukturyzowane są odpowiedzi.
Przykładowo, jak widzisz, tutaj odpowiedź
zwracana jest w formie obiektu, wewnątrz którego znajduje się właściwość
Rekord zawierającą tablicę konkretnych rekordów, o które pytamy.
Może to w tej chwili brzmieć jak mało znacząca informacja, ale uwierz mi, że
przyjdzie Ci się zastanawiać, w jaki sposób ustrukturyzowane taką odpowiedź.
Tym bardziej, że tutaj do gry wchodzi nie tylko to, w jaki sposób możemy wyświetlić
poszczególne rekordy, ale też w jaki sposób dostarczyć dodatkowe informacje,
takie jak chociażby w tym przypadku informacja o świecie, który jest niczym
innym jak elementem pagina umożliwiającym pobranie kolejnej porcji danych.
Zatem po raz kolejny mam nadzieję, że
widzisz wyraźnie, jak zmienia się moje spojrzenie na to, w jaki sposób
zaprojektowana jest aplikacja, z której korzystam wyłącznie jako użytkownik.
Otóż bardzo istotne jest dla mnie to, w
jaki sposób zorganizowane są te odpowiedzi, ponieważ takie wskazówki
będę w stanie wykorzystywać w momencie, gdy będę projektować własne API.
Podobnie też bardzo ciekawym wątkiem jest
chociażby podejrzenie sobie informacji na temat błędów, które są zwracane przez to
API, ponieważ pomimo tego, że jeżeli otworzysz sobie np.
Wikipedię i zobaczysz tam całą
obszerną listę wszystkich statusów odpowiedzi, tak w przypadku Twojego API
raczej przyjdzie Ci korzystać tylko z wybranych.
Wtedy nagle przekonasz się, że tak jak w przypadku tabel, wykorzystywanych jest
tylko kilka statusów odpowiedzi, zarówno w przypadku serwera jakich błędów
użytkownika, tak jednocześnie jest to przemyślane, spójne i przede wszystkim
użyteczne dla tego konkretnego projektu i użytkowników tego API.
Zatem bardzo Ci polecam jako takie ćwiczenie domowe, aby przejrzeć sobie API
popularnych narzędzi i serwisów po to, aby dowiedzieć się, w jaki sposób jest
dokumentowane, opisywane, w jaki sposób zaimplementowana jest
chociażby pagina cja, ponieważ tak jak widać w przypadku nowszych wykorzystujemy
tutaj mechanizm oparty o kursory i jednocześnie też mamy do czynienia z
wersjonowanie API, co również może się okazać ciekawą wskazówką dla Ciebie.
Podobnie też możesz przejrzeć sobie sposoby filtrowania oraz przyjmowania
parametrów, które odpowiadają właśnie za to działanie.
Zwróć uwagę, że chociażby w tym przypadku
mamy do czynienia z tak zaawansowanym filtrowaniem, że zamiast metody GET, która
jest raczej bardzo popularna w takiej sytuacji mamy do czynienia z metodą POST.
Wynika to z faktu, że po pierwsze parametry query string są na tyle
ograniczone, że można posługiwać się wyłącznie ograniczonym formatem danych.
Tak, jednocześnie ograniczone są również pod kątem długości.
I może okazać się, że w niektórych przypadkach złożona struktura filtru może
przekroczyć ten limit i tym samym uniemożliwić pobranie rekordów.
W przypadku metody POST taki problem jest
zdecydowanie mniejszy, ale jednocześnie też wiąże się z pewnymi ograniczeniami
wynikającymi chociażby z faktu, że nie można zapisać adresu URL
prowadzącego do konkretnego rezultatu pobranego z tego API.
Na sam koniec podkreślę raz jeszcze, że od
tego momentu warto patrzeć na dokumentację od tej drugiej strony, czyli tego, jakie
mechanizmy wykorzystują twórcy innych narzędzi i zastanawianie się, jak Ty
możesz wykorzystać to w swoich aplikacjach.
Jednocześnie chciałbym też po raz kolejny zaznaczyć, że przez dużą część tych
tematów będziemy sobie przechodzić jeszcze w kolejnych lekcjach.
W związku z tym, jeżeli coś nie jest na ten moment dla Ciebie jasne, to myślę, że
duża część z tych zagadnień stanie się dla Ciebie zrozumiała już niebawem.
Teraz dzięki za uwagę i do usłyszenia za chwilę.