Blazor, WASM a budoucnost webu
Lukáš Grolig
Něco málo o mně
- mnoho let SW developer a architekt
- v posledních letech se věnuji hlavně systémům využívajícím ML
Než začneme
BACKEND
FRONTEND
/
Dneska se budeme bavit hlavně o frontendu
Všechny spojuje
Který má ale své nevýhody
- dynamický
- slabě typovaný
- immutabilita
- paralelismus
- this
- pattern matching
- ADT
- ...
A někteří volali po návratu starých časů
A přišel Webassembly
A abysme měli i C#, tak velký Steve Sanderson stvořil Blazor
autor Knockout.js
C# kompilovaný do WASM
a hezké knihovny navrch
Výhody C# oproti JS
- kompilovaný
- silně typový
- podporuje koncepty FP (nic extra)
- teoreticky lepší performance
- a jak je zvykem u .NET - unifikovaný systém vývoje
A samozřejmě to má i své nedostatky
- stažení velkého balíku při otevření appky
- všechny funkce dostupné JS nejsou podporovány => občas je nutné volat JS
- SEO
- není tolik zdrojů
- stále existuje null
Vyplatí se to tedy použít na projektu?
Určitě
Teď k Blazoru
server side Blazor
2 modely
client side Blazor
Jaké jsou limitace klienta oproti serveru?
Teď k vytvoření projektu
dotnet new blazorwasm
dotnet new blazorserver
V CLI dle modelu
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
}
}
Vytvoření stránky v Pages
file s příponou .razor
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Kód a HTML v jednom souboru?
Je to dobré?
Předání parametrů
public class CounterClass : BlazorComponent
{
public int CurrentCount { get; set; }
[Parameter]
protected string SubTitle { get; set; }
public void IncrementCount()
{
CurrentCount += 5;
}
}
<Counter SubTitle="Subtitle from Index (Home) page"/>
Zpracování událostí
<button class="btn btn-primary" @onclick="UpdateHeading">
Update heading
</button>
@code {
private async Task UpdateHeading(MouseEventArgs e)
{
await ...
}
}
Formuláře
using System.ComponentModel.DataAnnotations;
public class ExampleModel
{
[Required]
[StringLength(10, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
}
Formuláře
<EditForm Model="@exampleModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText id="name" @bind-Value="exampleModel.Name" />
<button type="submit">Submit</button>
</EditForm>
@code {
private ExampleModel exampleModel = new ExampleModel();
private void HandleValidSubmit()
{
...
}
}
Načítání dat
builder.Services.AddScoped(sp =>
new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
Napřed konfigurace HTTP klienta
private class TodoItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
Potom vytvoření modelu
Načítání dat
@using System.Net.Http
@inject HttpClient Http
@code {
private TodoItem[] todoItems;
protected override async Task OnInitializedAsync() =>
todoItems = await Http.GetFromJsonAsync<TodoItem[]>(
"api/TodoItems");
}
A samotný request
Error Handling
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject IProductRepository ProductRepository
@inject ILogger<ProductDetails> Logger
@if (details != null)
{
<h1>@details.ProductName</h1>
<p>@details.Description</p>
}
else if (loadFailed)
{
<h1>Sorry, we could not load this product due to an error.</h1>
}
else
{
<h1>Loading...</h1>
}
Error Handling
@code {
private ProductDetails details;
private bool loadFailed;
[Parameter]
public int ProductId { get; set; }
protected override async Task OnParametersSetAsync()
{
try
{
loadFailed = false;
details = await ProductRepository.GetProductByIdAsync(ProductId);
}
catch (Exception ex)
{
loadFailed = true;
Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
}
}
}
Lokalizace a globalizace
Hotové komponenty
Například Telerik UI for Blazor
- super pro rychlo vytvoření projektu
- levnější než si dělat vlastní komponenty
- ale horší customizace komponent
Deployment
varianta server side:
- prostředí s nainstalovaným .NET
- je vhodné buildit a nasazovat přes docker kontejnery
varianta client side:
- pokud nepočítáme BE, tak stačí mít CDN
PWA
Webová aplikace chovající se jako desktopová appka
PWA
Webová aplikace chovající se jako desktopová appka
PWA
Je třeba přidat app manifest (manifest.json)
a ideálně vyřešit podporu pro offline práci (service workers a storage)
A jako u každého webového projektu musíme řešit mraky optimalizací
Doporučení pro projekty
- vyřešit autentizace a autorizaci hned na začátku (IdentityServer)
- hned udělat CI/CD
- deployment do AppService (kašlat na Kubernetes)
- kašlat na různý prostředí = dark deployment
- použít rozumný feature flag tool
- čas switchnout na Rider
Na závěr něco pro velký kluky
Když potřebujete spolehlivý soft a minimalizovat produkční exceptiony
-
Existuje F#
-
Doménové modelování přes ADT
-
Nepotřebujete design patterny
-
Nádstavba nad Blazorem je Bolero
-
Pro state management se využívá Elmish
To je pro dnešek vše
Dotazy?
Tak šťastné a veselé
Blazor, WASM a budoucnost webu
By Lukáš Grolig
Blazor, WASM a budoucnost webu
- 370