Piszę o programowaniu w ASPNET CORE. Jaką architekturę wybrać dla swojego projektu

blazor wasm

Blazor 101 – SPA w C#

Przeglądając materiały w tematyce programowania na platformie .NET, trudno nie zauważyć hype’u na Blazora. Zapowiada się wręcz rewolucyjny produkt, który będzie CyberPunkiem WebDevu. I tak jak w przypadku gry od CD PROJEKT RED, tak i frameworka od Giganta z Redmond, pytanie brzmi – „Czy jest już gotowy?”.

Co nas boli w MVC

Każde nowe rozwiązanie powinno rozwiązywać jakąś grupę problemów. Jak popatrzymy na dotychczasowy rynek Web Developmentu to mamy kilka opcji:

  1. Tworzymy statyczne strony (np. landing page) przy użyciu HTML + CSS (+ minimalna ilość JavaScript). Minusem jest mała interaktywność, przez co trudno nazwać to aplikacją – bardziej przypomina interaktywny plakat.
  2. Poznajmy jakiś framework typu ASP.NET CORE, Spring, Laravel, Rails, Django i piszemy aplikacje typu MVC gdzie widoki są dynamicznie generowane per request.
    • Nadal nie mamy wpływu na to co się wykonuję po stronie przeglądarki. Przez co User Experience (czyli to jakie odczucia ma użytkownik z korzystania z naszej aplikacji) nadal jest słaby.
  3. Ostatnią opcja jest połączenie punktu 2. z nauka znienawidzonego języka JavaScript – czyli zostajemy FullStackiem. Oczywiście nie musimy pisać w czystym JS, możemy używać Angulara, Reacta, Vue czy setki innych frameworków/bibliotek.
    • Jednak problemem jest to że musimy podzielić swój czas na naukę dwóch języków.
    • Musimy się pogodzić z dynamicznym typowaniem po stronie przeglądarki – każdy kocha literówki ❤.
    • Dodatkowym minusem jest brak możliwości współdzielenia już napisanego kodu, czyli wszystkie modele muszą być napisane i w C# i JS.

I tutaj pojawia się Blazor, a dzięki niemu:

✅ tworzymy interfejs użytkownika używając naszego ukochanego C#

✅ możemy współdzielić kod (modele danych, zapytań, odpowiedzi)

✅ komponenty raz napisane, mogą być wykorzystywane przez wiele aplikacji – możliwe jest tworzenie własnych bibliotek komponentów

✅ nadal możemy używać HTML, CSS a nawet JSa. Blazor zapewnia interoperacyjność z JavaScriptem przez co dowolnie możemy używać znanych nam już bibliotek (np. Three.js)

Czym jest Blazor?

Jest on frameworkiem do tworzenia interaktywnych aplikacji webowych (SPA like). Czyli pozwala nam pisać kod który będzie się wykonywał w przeglądarce – tak jak JavaScript. Korzystamy w nim z składni znanej już z MVC czyli Razora. Jednak nie opieramy się o model request-response.

Z racji że jest to produkt oparty o platformę .NET CORE to możemy korzystać z wszystkich dobrodziejstw jakie za tym idą:

  • łatwa konteneryzacja
  • Visual Studio / Rider / Visual Studio Code
  • IntelliSense
  • biblioteki
  • wysoka wydajność
  • bezpieczeństwo

Osobiście mając podstawy Angulara mam wrażenie że używanie Blazora to takie pisanie aplikacji Angularowej, ale lepszej – bo w C# 😜.

Microsoft wydał do tej pory dwie wersje frameworka (i chodzą słuchy o kolejnych!). Pierwszy był Blazor Server, opierający się o stałą komunikację po WebSocket’cie (SignalR). Wersja ta naprawdę robi wrażenie jeśli chodzi o to jak „sprytnie oszukuje użytkownika”.

19.05.2020 wraz z publikacją .Net Core 3.1 światło dzienne ujrzała oficjalna wersja BLAZOR WEBASSEMBLY (WASM), czyli implementacje oparta standard wprowadzony przez World Wide Web Consortium (W3C). Zaś od 10.11.2020 dostaliśmy do dyspozycji rozszerzone API, z netstandard2.1 do .NET 5. W przeciwieństwie do wersji Sever, kod wykonywany jest w pełni po stronie przeglądarki – w tym samym sandboxie co JavaScript.

Frame It All 33 Tool-Free Classic Sienna Two Inch Series 84'' Plastic Wood  Grain Brown Play Sandbox & Reviews
https://secure.img1-fg.wfcdn.com/im/37338478/compr-r85/5019/50193763/33-tool-free-classic-sienna-two-inch-series-84-plastic-wood-grain-brown-play-sandbox.jpg

Oszust

Tak można nazwać Blazor Server. Ponieważ mimo że kod wykonuje się po stronie serwera, to nie dokonywane jest przeładowanie strony (tak jak ma to miejsce w MVC). Kluczem do tego jest stałe połączenie oparte o SignalR.

::: No-Loc (Blazor webassembly):::: w wątku interfejsu użytkownika w przeglądarce zostanie uruchomiona aplikacja No-Loc (Blazor)::: App.
https://docs.microsoft.com/pl-pl/aspnet/core/blazor/hosting-models?view=aspnetcore-5.0
  1. Podczas ładowania strony pobierany jest plik blazor.server.js który nawiązuję połaczenie (websocket) z serwerem, jednocześnie tworząc unikatową sesję.
  2. Po stronie serwera tworzony jest graf zawierający stan poszczególnych komponentów.
  3. Niektóre interakcje użytkownika z UI (np. wciśniecie przycisku) wiążą się wysłaniem wiadomości z odpowiednimi informacjami do serwera.
  4. Serwer posiadający kopie stanu naszej aplikacji (graf) wykonuję dana akcję oraz nanosi zmiany w drzewie DOM (czyli obiektowej reprezentacji struktury HTML)
  5. Następnie wyliczana jest różnica sprzed i po wykonaniu akcji (diff), która jest wysyłana po WebSocketcie w postaci binarnej do aplikacji klienckiej. Różnica zawiera najmniejszy podzbiór edycji DOM’u wymagany do zaktualizowania interfejsu użytkownika.
  6. Ostatnim krokiem jest zaktualizowanie DOM o otrzymana różnicę.
  7. W momencie gdy użytkownik opuści widok danego komponentu informacje o stanie (danego elementu) zostają usunięte.

Z powodu że stan każdej instancji aplikacji znajduję się w pamięci serwera to należy uważać na to co przetrzymujemy w aplikacji. Zalecane jest korzystane m.in z paginacji oraz wirtualizacji. Więcej wskazówek znaleźć możecie tutaj -> LINK

Fragment prezentacji tyczący się wydajności Blazor Server autorstwa Carl Franklin.

WebAssembly

W tej wersji przenosimy się z naszym kodem do przeglądarki. Jest możliwe to dzięki standardowi WebAssembly. Jest to język zapisu binarnego, dzięki któremu możemy kompilować kod napisany w np. C++, C#, RUST i uruchamiać go w tym samym sandboxie co JavaScript.

Dzięki takiemu rozwiązaniu mamy dostęp do tego samego zbioru API przeglądarki, czyli np. DOM, CSSOM, WebGL, IndexedDB, Web Audio API. Jednocześnie zachowujemy wysoką wydajność (jak podaje dokumentacja „near-native”) oraz bezpieczeństwo (z racji środowiska uruchomieniowego).

WebAssembly: How and why - LogRocket Blog
https://storage.googleapis.com/blog-images-backup/1*4ZMcCrF95AUvVzJ4S6Lo-g.png

Często porównywany jest do Flasha ✝ oraz Silverlighta ✝. Tworzą się przez to obawy, że tak jak te dwie technologie, tak i WASM nie będzie wspierany przez niektóre przeglądarki i koniec końców umrze. Żeby zrozumieć dlaczego możemy być spokojni należałoby się cofnąć w czasie i dowiedzieć na czym polegał problem.

Bez wchodzenia w szczegóły, zarówno Flash i Silverlight opierały się o model pluginów do przeglądarek. Był on bardzo dziurawy i dawał duże pole manewru dla złośliwego oprogramowania. Z tych powodów m.in Apple w swoim Safari postanowili nie wspierać tego modelu. Podsumowując WASM to nie plugin, powinniśmy postrzegać go jako zamiennik JSa – a raczej dopełnienie.

Blazor WASM

Tak jak pisałem w poprzednim punkcie w tej wersji nasz kod wykonuję się w oknie przeglądarki. Co za tym idzie musimy myśleć o naszej aplikacji jak o SPA. Przykładowo nie będziemy tutaj przechowywać wrażliwych danych takich jak connectionString do bazy danych, hasła czy klucze do API.

Tak jak w aplikacjach SPA, przy pierwszym uruchomieniu pobierana jest nasza aplikacja plus brakujący statyczny kontent – obrazki, ikony czy pliki dźwiękowe. W naszym przypadku musimy jeszcze pobrać środowisko uruchomieniowe „Mono .NET„.

Pierwsze uruchomienie aplikacji wiążę się z dłuższym ładowaniem strony z racji konieczności pobrania Mono.NET

Podaję się wartość 6MB jako konieczną do pobrania w trybie debug oraz 1.8MB w release, jednak gdy uruchomimy pusty projekt to zobaczymy wartości ponad 9MB. Jednak pamiętajmy że niemalże wszystko zostanie z cache’owane, dzięki czemu kolejne załadowania to ~5kB. Dla porównania strona logowania do Facebooka waży 1MB (z użyciem cache’a!).

Jednak dzięki cache-owaniu przez przeglądarkę kolejne uruchomienia już są o wiele szybsze 🙂

Pamiętajmy, Blazor WASM = SPA, czyli możemy dodać PWA oraz wsparcie trybu offline (co jest niemożliwe w wersji Server). Kolejną cechą idącą za tym jest możliwość dystrybuowania aplikacji przy użyciu CDN zamiast klasycznego modelu hostowania.

Jednak nie zapominajmy o tym co najważniejsze, Blazor WASM służy do pisania interfejsu. W większości przypadków będziemy wizualizować dane które otrzymamy z jakiegoś API. Szkoda tylko że nie można mieć backendu i frontendu napisanego w jednym języku, by móc wykorzystać modele zapytań i odpowiedzi w obu projektach. Ups… przecież można, i nie mówię tu o Nodejs + JS! 🅱

Blazor vs .NET 5

Ten punkt jest głównie dla osób co miały już styczność z Blazor WASM w wersji preview. Zamieszczę tu główne zmiany jakie nastąpiły pomiędzy .NET CORE 3.1 a .NET 5.

W preview bolączką wielu osób było to że projekt Blazorowy kompilowane były pod wersję „.NET Standard 2.1”. Łączyło się to z koniecznością korzystania z starszych wersji bibliotek bądź brakiem możliwości ich użycia.

Konsekwencją czego projekt („Shared”) który zawierał współdzielone elementy pomiędzy API a WASM nie mógł korzystać z .NET CORE, przez co musieliśmy bardziej uważać co umieścimy w danym projekcie.

Jednak wraz z w wprowadzeniem .NET 5 wszystkie projekty mogą być kompilowane pod jedną platformę, dzięki czemu w pełni korzystać z bibliotek znanych z wersji CORE i wyżej.

Jest małe ALE.

Jeśli chcielibyście napisać własny szyfrowany komunikator (E2E) typu WhatsUp czy Signal, to nie obejdziecie się bez skorzystania z bibliotek JS’owych, lub własnych implementacji funkcji kryptograficznych.

System.Security.Cryptography nie jest dostępne dla Blazor WASM

Powyższy nagłówek mówi sam za siebie. Pytanie brzmi: DLACZEGO?! Odpowiedz znajduję się w dokumentacji i brzmi następująco:

Microsoft is unable to ship OpenSSL as a dependency in the Blazor WebAssembly configuration. We attempted to work around this by trying to integrate with the browser’s SubtleCrypto API. Unfortunately, it required significant API changes that made it too hard to integrate.

Microsoft

Nie tyczy się to wszystkich bibliotek. Te podstawowe, gdzie znajdziemy funkcje skrótu oraz generator liczb pseudolosowych są będą dostępne.

Jest to dla mnie szczególnie smutne z racji że mój pierwszy projekt w Blazorze to był właśnie komunikator szyfrowany. Cóż kolejny „pet project” musi czekać na lepsze czasy 🙂

Server vs WASM – Pros and Cons

Server

✅ Szybkie pierwsze uruchomienie aplikacji

✅ Możemy bezpośrednio korzystać z DbContext-u

✅ Działa na starszych przeglądarkach które nie obsługują WebAssembly

✅ Możemy przechowywać dane wrażliwe (connection string, api secret)

❌ W zależności od dostępu do sieci mogą występować problemy z opóźnieniem

❌ Brak wsparcia trybu offline

❌ Skalowalnie – wąskim gardłem jest Hub SignalR

❌ Wymagane jest hostowanie z serwera ASP.NET CORE (brak możliwości wykorzystania CDN – serverless)

WASM

✅ Tryb Offline

✅ Wysoka wydajność

✅ PWA

✅ Możliwość korzystania z CDN (Serverless)

❌ Duże początkowe pobierania (~8Mb)

❌ Wciąż problematyczne debugowanie

❌ Wymagane przeglądarki obsługujące WASM

❌ Brak możliwości przechowywania danych wrażliwych

❌ Brak możliwości korzystania z bibliotek kryptograficznych

Przyszłość Blazora

W wpisie Daniela Roth możemy przeczytać o przyszłości Blazora. Pisze on o prowadzonych eksperymentach nad zaadaptowaniem składni do użycia nie tylko w technologia webowych, a w Elektronie oraz Xamarinie. Jest to próba stworzenia uniwersalnego frameworka do tworzenia UI.

Wygląda na to że zespół próbuje abstrahować od mechanizmu który będzie to renderował. Przez co może to zaowocować czymś naprawdę ciekawym! Czekam z niecierpliwością, tak jak i na kolejne wersje Blazor Server i WASM (szczególnie na System.Security.Cryptography !!!).

Bonus -> Seria + Ebook

Postanowiłem zrobić serię o Blazorze. Będę chciał w niej poruszyć podstawowe problemy rzeczy które najczęściej są nam potrzebne:

  • Tworzenie komponentów
  • Komunikacja z API
  • Uwierzytelnianie użytkowników
    • Cookie Auth
    • JWT Auth
      • Custom
      • oAuth2 + OpenID Connect
  • Obsługa formularzy
  • Interoperacyjność z JavaScript
  • Przydatne biblioteki
  • Praktyczny deploy na
    • lokalnej stacji/VM
    • Azure
    • CDN

Kolejne wpisy będą tutaj linkowane, a sam spis treści będzie ewoluował. Jeśli chciałbyś bym poruszył coś co szczególnie Cię interesuje – napisz komentarz! Pomoże mi to stworzyć materiał który będzie pomocny dla każdego kto będzie chciał nauczyć się Blazora.

Zwieńczeniem tej serii będzie stworzenie e-booka. A jeśli chciałbyś dostawać:

  • wersję beta ebooka (oczywiście gdy będzie już gotowa)
  • informację kiedy będzie dostępny
  • informację o nowych wpisach (nie częściej niż raz w miesiącu)
  • informację o ciekawych linkach związanych z Blozorem i .NET

to zapisz się na newsletter. Nie będzie spamu – obiecuję, nie przewiduję więcej niż 2 maile miesięcznie. Link znajduję się >TUTAJ<.

Przydatne linki

  1. Blazor Train https://blazortrain.com/
  2. Carl Franklin’s Blazor Desk Show with Dan Roth https://www.youtube.com/watch?v=xxIkh6GZdaM&t=1597s&ab_channel=DevExpress
  3. Materiały z pkt2. https://blazordeskshow.com/carl-franklins-blazor-desk-show-v2.2.zip
  4. Dokumentacja https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor
  5. Threat mitigation guidance for ASP.NET Core Blazor Server https://docs.microsoft.com/pl-pl/aspnet/core/blazor/security/server/threat-mitigation?view=aspnetcore-5.0
  6. ASP.NET Core Blazor hosting models https://docs.microsoft.com/pl-pl/aspnet/core/blazor/hosting-models?view=aspnetcore-5.0
  7. ASP.NET Core Blazor component virtualization https://docs.microsoft.com/pl-pl/aspnet/core/blazor/components/virtualization?view=aspnetcore-5.0

Previous

Programowanie 101. Enkapsulacja, hermetyzacja czy kapsułkowanie?

Next

Blazor 102 – Zacznijmy od WebAssembly

2 Comments

  1. shinymetalrobot

    Fajnie tak hejtować JS ale mamy już rok 2020 a nie 2010 i parę rzeczy się od tego czasu zmieniło.
    1. IDE już świetnie ogarniają JSa wiec literówki stały się pieśnią przeszłości.
    2. „Typescript is a thing” więc możesz sobie pisać te same interfejsy których użyjesz na backendzie i frontendzie.

    A generalnie to kibicuje blazorowi i niech WebAssembly rośnie w siłę.

  2. Osobiście bardzo mocno kibicuje Blazorowi. Szczególnie może ułatwić pracę w małych zespołach/projektach, gdzie bardzo często kończyło się na tym, że różne osoby robiły frontend i backend. A jednak łatwiej jednej osobie ogarnąć Blazor + .NET, niż na przykład React + .NET.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Powered by WordPress & Theme by Anders Norén