Trudny / egzaminacyjny · lekcja 12

ASP.NET Core jako backend dla Angular — Web API i CORS

Masz już gotowy frontend w Angularze (lekcje 9-11) i wiesz, jak budować backend w ASP.NET Core (lekcje 3, wcześniejsze doświadczenia). Czas je POŁĄCZYĆ. Backend, który komunikuje się z frontendem SPA, nie zwraca gotowego HTML — zwraca WYŁĄCZNIE dane (najczęści...

Zacznij tutaj

Po co się tego uczymy?

Masz już gotowy frontend w Angularze (lekcje 9-11) i wiesz, jak budować backend w ASP.NET Core (lekcje 3, wcześniejsze doświadczenia). Czas je POŁĄCZYĆ. Backend, który komunikuje się z frontendem SPA, nie zwraca gotowego HTML — zwraca WYŁĄCZNIE dane (najczęściej JSON), a Angular sam decyduje, jak je wyświetlić. Ta lekcja pokazuje Web API w ASP.NET Core oraz mechanizm CORS, bez którego Angular (inny port!) w ogóle nie mógłby połączyć się z Twoim backendem.

Wprowadzenie

Teoria

Kontroler API dziedziczy po ControllerBase (nie po Controller, który dodatkowo obsługuje widoki HTML — Web API ich nie potrzebuje, bo cały interfejs buduje Angular). Atrybut [ApiController] nad klasą włącza automatyczną walidację modelu (jeśli dane są niepoprawne, ASP.NET Core SAM zwraca błąd 400, zanim kod w ogóle wejdzie do metody) i inne usprawnienia typowe dla API.

Atrybuty routingu HTTP — każda akcja jawnie deklaruje metodę HTTP, którą obsługuje:

AtrybutMetoda HTTPTypowe zastosowanie
[HttpGet]GETpobranie danych (lista albo pojedynczy element) — wywoływane przez Angular HttpClient.get()
[HttpPost]POSTutworzenie nowego zasobu — HttpClient.post()
[HttpPut("{id}")]PUTpełna aktualizacja — HttpClient.put()
[HttpDelete("{id}")]DELETEusunięcie — HttpClient.delete()

CORS (Cross-Origin Resource Sharing) — dlaczego jest KONIECZNY w tym układzie. Twój Angular działa (podczas developmentu) pod adresem http://localhost:4200, a backend ASP.NET Core pod zupełnie INNYM adresem/portem (np. https://localhost:7042). Przeglądarka ze WZGLĘDÓW BEZPIECZEŃSTWA domyślnie BLOKUJE żądania JavaScript/TypeScript do INNEJ domeny/portu niż ta, z której strona została załadowana — to mechanizm CORS. Backend musi JAWNIE zezwolić na żądania z adresu Angulara: builder.Services.AddCors(opt => opt.AddPolicy("AngularApp", p => p.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader())); oraz app.UseCors("AngularApp");. Bez tej konfiguracji Angular dostanie błąd w konsoli przeglądarki, mimo że backend "działa poprawnie" (bo problem jest po stronie reguł bezpieczeństwa przeglądarki, nie samego API).

Typy zwracane — ActionResult<T>. Ok(dane) (200, z danymi), NotFound() (404), BadRequest("komunikat") (400), CreatedAtAction(...) (201, po udanym POST) — te same kody odpowiedzi HTTP, które sprawdzasz po stronie Angulara w bloku .subscribe() albo try/catch przy async/await.

Konsumpcja API z Angulara — HttpClient. Angular ma wbudowaną usługę HttpClient (wstrzykiwaną przez konstruktor, dokładnie jak serwisy z lekcji 10) do wysyłania żądań HTTP: this.http.get<Produkt[]>('https://localhost:7042/api/produkty') zwraca Observable (strumień danych w czasie — koncepcja z biblioteki RxJS, używanej wewnętrznie przez Angular) — subskrybujesz go metodą .subscribe(dane => { ... }), żeby odebrać dane, gdy faktycznie dotrą z serwera.

Testowanie API narzędziem Postman (z lekcji 2) — zanim frontend Angular zacznie korzystać z Twojego API, warto samodzielnie sprawdzić w Postmanie, czy każdy endpoint zwraca oczekiwane dane.

Zobacz zależności

Schemat

Żądanie GET /api/produkty
        │
        ▼
ProduktyApiController.GetWszystkie()  [HttpGet]
        │
        ▼
context.Produkty.ToListAsync()
        │
        ▼
return Ok(produkty);   → odpowiedź JSON: [{"id":1,"nazwa":"...","cena":89.99}, ...]

Żądanie POST /api/produkty (treść: JSON nowego produktu)
        │
        ▼
ProduktyApiController.Dodaj(Produkt nowy)  [HttpPost]
        │
        │  [ApiController] AUTOMATYCZNIE waliduje - jeśli błąd, zwraca 400 bez kodu w akcji
        ▼
context.Produkty.Add(nowy); SaveChangesAsync();
        │
        ▼
return CreatedAtAction(nameof(Pobierz), new { id = nowy.Id }, nowy);  → 201 Created

Klient (JavaScript fetch / aplikacja MAUI HttpClient / Postman)
        │
        ▼
odbiera odpowiedź JSON, przetwarza dalej

Połącz z praktyką

Przykład z życia

Aplikacja sklepowa w Angularze wyświetla listę produktów pobraną z Twojego własnego backendu ASP.NET Core — dokładnie ten sam mechanizm REST API, którego aplikacja MAUI używała jako klient w dziale mobilnym (HttpClient po stronie C#), tylko teraz klientem jest Angular (HttpClient po stronie TypeScript), a Ty budujesz OBIE strony tej komunikacji.