Projektowanie Serwera
2 godz. 7 min · Full-stack i Programowanie
Przemysław NowakSoftware EngineerJeżeli kiedykolwiek używałeś GraphQL aby pobrać dane na Front-endzie to z pewnością wiesz, że aby to zrobić musisz znać połączenie Grafów oraz wiedzieć jak stworzyć odpowiednie zapytanie. W kursie tym nauczysz się jak takie grafy projektować od strony serwera i dostarczać je dla FrontEnd Developerów.
Dowiesz się jakie jest połączenie pomiędzy schematem serwera a resolverami. Schemat (schema) to nic innego jak opis aplikacji GraphQL z podziałem na typy i relacje - właśnie w taki sposób tworzą się grafy - natomiast resolvery są odpowiednikami w kodzie - wykonującymi się za każdym razem kiedy ktoś wysyła odpowiednie zapytanie. Dokładnie wytłumaczę Ci korelację pomiędzy tymi dwiema rzeczami oraz na konkretnych przykładach zrozumiesz jak je implementować.
Statystyki są nieubłagane - coraz więcej firm inwestuje w GraphQL ze względu na rewolucyjne podejście do pobierania danych oraz jego prostotę. Dlatego jeżeli spojrzymy na rynek pracy to możemy zobaczyć, że GraphQL staję się pewnego rodzaju "must have", którego z pewnością warto się nauczyć.
Przekonasz się, że tworzenie backendu z GraphQL jest niesamowicie szybkie. Kiedy zrozumiesz podstawowe połączenia schematu i resolverów nic Cie nie powstrzyma od błyskawicznego pisania kodu. Jeżeli chcesz stworzyć MVP, czy zaimplementować elastyczny mikro serwis to GraphQL może okazać się strzałem w dziesiątke dlatego, że możesz stworzyć aplikację z prędkością światła, a co więcej, każda rozbudowa jest bardzo prosta ze względu na brak zależności w kodzie.
Tego wszystkiego nauczysz się w tym kursie, odczyt i zapis danych wydają się rzeczą normalną, natomiast dla mnie najciekawszą rzeczą są subskrypcje dzięki, którym możesz tworzyć aplikacje działające w czasie rzeczywistym. Zobaczysz, że z GraphQL wcale to nie jest skomplikowane, a wręcz banalnie proste!
Kurs ten jest skierowany do osób, które mają podstawową wiedzę nt. GraphQLa oraz znają podstawy JavaScript - ponieważ za pomocą NodeJS zaimplementujemy serwer GraphQL. Jeśli jeszcze tego nie zrobiłeś/aś - polecamy przed przystąpieniem do tego kursu przerobienie materiałów JavaScript od Podstaw, kursu podstawowego GraphQL, a mile widziana jest także znajomość zagadnień z kursów Node.js.
Pokażę Ci czym są schematy i recovery,
czyli najważniejsza część jeżeli chodzi o cele.
Jesteśmy w miejscu, w którym skończyliśmy, więc odpalamy server.
I mamy tutaj wygenerowaną metodę. Heloł!
Przejdźmy do braku planu naszego programu.
Jeżeli zerkniemy na dokumentację, to mamy tutaj metodę Hello, która zwraca string
i ta metoda przyjmuje również argument name, więc jeżeli ją teraz wykonamy.
I podamy ten argument Name.
Niech to będzie moje imię.
To teraz powinniśmy dostać jakiegoś stringa i ok, mamy tutaj.
Heloł Przemek!
I teraz kiedy zerkniemy na schizmę to możesz zauważyć, że to jest dokładne to
odwzorowanie typu root query, czyli to jest ten nasz ród query.
Możemy nawet explicite napisać, że jest to
query i mamy tutaj heloł, które przyjmuje jakiś argument.
Jest to name, które musimy tutaj podać.
Jest to typ string i zwraca to również typ string i nie może to zwrócić null.
Czyli zawsze to będzie zwracało stringa.
I tutaj również nie musimy podawać tego name.
Czyli jeżeli byśmy teraz to heloł.
Może wzięlibyśmy tego? Heloł?
To heloł! Wykonali bez argumentów.
No to mamy po prostu Hello world!
I to jest przykład naszego Heloł!
Przejdźmy do kodu i zobaczmy jak to wygląda, by to zrozumieć.
To jest dokładnie definicja tej,
którą widzieliśmy, czyli mówimy, że dla typu root query
definiujemy heloł, które przyjmuje właśnie jako string, zwraca stringa itd.
Dalej czyli to jest cała nasza definicja z kim?
I na podstawie tej z kim będziemy
wykonywać query w w w programie czy tam w aplikacji.
I tutaj możemy teraz zerknąć na recovery
i recovery mają dokładnie to samo odzwierciedlenie.
Czyli mamy tutaj typ query,
który jest swoją drogą router, czyli jest to root query.
Ten typ zawsze musimy mieć zdefiniowany
i ten typ mówi, że ma takie pole jak heloł i dlatego heloł mamy tutaj implementację.
Co się ma zdarzyć? Jak to heloł zostanie wykonane?
I żeby się tutaj przyjrzeć, może po prostu
podajmy to tak jak to wygląda w stanie surowym?
Czyli mamy tutaj Parent, mamy RX
i tutaj może też zwróćmy to w taki sposób, byś wiedział dokładnie co się dzieje.
Do heloł przypisujemy metodę arrow function,
która jako pierwsza argument dostaje parent, natomiast tutaj jego rodzicem.
Nie ma tak naprawdę heloł, nie ma rodzica, ponieważ jest to root, czyli
jesteśmy w czyli w query natomiast może mieć jakieś argumenty i pod
argument kryje się dokładnie to co przekazujemy tutaj.
Teraz musimy tutaj zwrócić.
Czyli tutaj zwracamy stringa, czyli dokładnie to co mamy tutaj zdefiniowane
i zwracamy Heloł, Jeżeli jest name, czyli jeżeli jest nam przekazane teraz żeby to
działało to poprawna forma jest taka No to jeżeli jest name to zwrócimy.
Heloł!
I ten argument, który przekazaliśmy, a jeżeli nie to po prostu Hello world.
I tak jak wspomniałem mamy tutaj parents i ten parent będzie się liczył do innych
typów pól, ponieważ dla query parent zawsze będzie null.
Dlatego dobrą praktyką jest po prostu dodać tutaj under skora.
Dobrą praktyką jest również
zrestrukturyzować obiekt i bezpośrednio używać name w takim przypadku.
Tutaj możemy również pozbyć się tego return i wtedy mamy po prostu.
Arrow function. Name.
Więc stwórzmy teraz jeszcze jeden typ.
Ja bym chciał tutaj dodać typ message.
Jan również może przyjąć pole.
I to pole name będzie również string.
Natomiast ja znaczę je jako wymagane.
I również zwrócimy tutaj swój typ, czyli wielka.
I teraz jeżeli zdefiniujemy w tym miejscu message type.
To może mam podać pola jakie powinien zwrócić?
Ja powiem, że to będzie message.
Natomiast jeszcze bym tutaj mógł dodać np.
country i to country.
Niech to będzie string. Message.
Niech to będzie string.
OK. I teraz jeżeli popatrzymy sobie
na rewolwer, to tak jak mówiłem to jest idealna korelacja pomiędzy query w
definicji w sumie i query w definicji w rowerach.
Więc teraz jeżeli tutaj dodam ten wielki message.
To również będzie taka korelacja
i możemy tutaj dodać kilka message aby rezerwować się na tych polach, ale tylko i
wyłącznie jeżeli chcemy żeby te pola w jakiś szczególny sposób się rezerwowane.
Jeżeli tego nie chcemy to możemy po prostu na Type Query zrobić wielka message.
To również będzie metoda.
Tak jak pamiętasz Barentsa tutaj nie mamy
dostępnego, natomiast mamy argumenty i tutaj również będziemy mieć argument name.
I to, co będziemy chcieli zwrócić to będzie obiekt.
Obiekt, który zwróci uwagę.
I niech to będzie message.
I niech to będzie również country i country.
Niech to będzie polem.
Na przykład.
OK.
Teraz jeżeli wykonamy sobie to pole OK i zobaczmy co jest nie tak.
Brakuje tutaj przecinka.
Teraz powinno być ok.
I teraz jeżeli wykonamy to query w. Program.
Czyli wykonajmy tutaj wielką message,
przekażmy name i również tutaj przekażę swoje imię.
To teraz mogę kolorować oczywiście na
polach, czyli to co już znasz zapewne z pierwszej części kursu.
Niech to będzie country i message.
Teraz jeżeli wykonam to query.
To dostałem Przemek i dostałem jako pole.
Natomiast tak naprawdę jeżeli bym chciał teraz wykonać jakieś osobne akcje dla
Message czy Country to mogę odzwierciedlić scheme.
Czyli jeszcze raz odzwierciedla i dodaje tutaj wielka message.
Będzie to obiekt i mogę powiedzieć, że dla pola message.
Chcę zrobić jakąś swoją implementację
i tutaj tym patentem będzie to, co zwróciliśmy w tym
naszym patencie, czyli tak naprawdę tym patentem jest to.
Więc tutaj mamy taki parę argumentów.
Tutaj nie mamy żadnych,
ponieważ gdybyśmy chcieli jakieś argumenty, to musielibyśmy tutaj jakieś
argumenty dopisać, przykład jakieś ARG 1 itd.
My tutaj nie dodajemy żadnych argumentów.
Ale możesz to oczywiście zrobić.
Więc to jest w zasadzie nam niepotrzebne.
I teraz powiemy, że ten message będzie miał coś zwrócić.
Ja powiem na początku, że Parent
zwróci nam country, natomiast message zwróci pusty.
Ponieważ nie chcę narazie tutaj nic
zwracać, ale chciałbym żeby jeszcze ten parent zwrócił tutaj name.
Czyli chciałbym przekazać do wszystkich
pól do wszystkich dzieci tak naprawdę, czyli tych pól dzieci.
To pole name, które dostałem w tym miejscu.
A więc w tym miejscu po prostu powiem, że chcę zwrócić message.
To będzie string, ponieważ
tutaj mamy zdefiniowane jako string i to będzie wielka.
Kocham.
I teraz parents dostajemy name.
Czyli możemy to zobacz na ten przykład.
I możemy powiedzieć w jakim kraju.
Czyli zdefiniujemy taką wiadomość.
OK, znowu mamy jakiś błąd.
Brakuje nam tutaj przecinków. OK.
W porządku.
Wróćmy i wykonajmy jeszcze raz to Query.
No i teraz mam już tutaj wszystkie informacje.
Czyli mam tutaj zbudowany message na podstawie tego, co mi zwrócił rodzic.
Dlaczego to jest generalnie ważne?
Jeżeli sobie wyobrazi, że ktoś tak naprawdę nie kieruje na tym polu message.
Czyli chcę zwrócić
w tej wiadomości tylko prawdę, to nie musisz wykonywać wszystkich akcji,
które tutaj wykonał w tym resolve czyli message.
Dlatego warto jest pisać resolve osobne dla pól.
Jeżeli są to jakieś pola bardziej
wymagające, w tym przypadku jest to po prostu string.
Natomiast gdybyś tutaj robił jakieś
trudne obliczenia czy jakieś query do AP, do serwera itd.
I korzystał z jakiegoś API to wtedy nie ma sensu tego robić.
Bo tak naprawdę gdybyś tutaj zrobił całą
tą implementację i tutaj zrobił całe wykonanie query np.
w funkcji samo wywołującej się.
Tutaj byś zrobił kol.
I tak dalej i potem zwrócił coś jeszcze, byś np.
coś liczył, wykonywał funkcje
skomplikowane czyli byś wykonał całą pracę jaką musi być wykonana
dla danego pola to nawet jeżeli byś kierował tylko po
country to i tak ten kod by się nam wykonał ponieważ jest tutaj samo wywołanie
więc ten kod by się nam wykonał i to jest problem.
Generalnie nie powinniśmy tak robić.
Powinniśmy dodać to do osobnego pola i wtedy tylko i wyłącznie jeżeli będziesz
kierował na tym polu to tylko wtedy ta funkcja się wykona.
Czyli jeżeli teraz w tym przypadku
wykonają query tylko na country, to ta funkcja się tak naprawdę nie wykonała.
Natomiast jeżeli byłoby to tutaj zdefiniowane to ta funkcja zawsze by się
wykonała i to jest ważna dobra praktyka, aby tworzyć właśnie recovery dla pola.
Natomiast najważniejsze jest żebyś zrozumiał tą korelację pomiędzy schematem.
Tutaj definiujesz schemat całego naszego serwera.
Jakie mamy metody, jakie przyjmują te metody, argumenty co
zwracają I tutaj w rezultatach musisz po prostu odzwierciedlić całą tą strukturę.
Mam nadzieję, że już rozumiesz jak
działają Scheme i recovery i jak są ze sobą połączone.
Jeżeli nie, to proszę Cię obejrzyj tę
lekcje jeszcze raz, ponieważ jest to kluczowa część jeżeli chodzi o Powella.
Jeżeli rozumiesz, to zapraszam Cię do kolejnej lekcji.