WordPress importer w .NET — projekt na praktyce

Startujemy serię, w której budujemy realną aplikację konsolową w .NET 6 — importer ogłoszeń z Google Places API do WordPressa. Plan i stos wewnątrz.

JAJarosław Armatys 6 min czytania
Wersja wideo tego wpisu — obejrzyj na YouTube

Co tu będziemy budować

Witaj w pierwszym odcinku serii, w której nie uczymy się .NET-a na przykładach z kosmosu, tylko budujemy coś, co faktycznie rozwiązuje problem biznesowy. Wyobraź sobie marketplace z ogłoszeniami firm fotowoltaicznych — prawdziwa strona na WordPressie, zwykli użytkownicy, zwykłe wyszukiwanie. Problem: baza 55 tysięcy firm, które trzeba tam wrzucić. Ręcznie? Dwie minuty na ogłoszenie to tygodnie klikania w panel administracyjny. Nikt przy zdrowych zmysłach się tego nie podejmie.

Więc robimy to inaczej — piszemy aplikację konsolową w .NET 6, która zaciąga firmy z bazy danych, wzbogaca je o dane z Google Places API (telefon, godziny otwarcia, współrzędne do mapy, opinie), po czym wystrzela gotowe ogłoszenia do WordPressa przez REST API. Na dokładkę zrobimy bota w Selenium, który zaloguje się na stronę jako użytkownik i doda opinie z gwiazdkami — bo akurat tego WordPress API nie obsługuje w sensowny sposób.

To nie jest kolejny kurs, w którym robimy listę todo albo kalkulator. Lecimy na prawdziwym projekcie, z prawdziwymi problemami i prawdziwym deploymentem do działającej strony.

Jeżeli jesteś po podstawach C# i chcesz zobaczyć, jak to wygląda w praktyce — usiądź wygodnie, bo ta seria będzie konkretna.

Stos technologiczny

Zanim przejdziemy do planu, zobacz z czym będziesz pracować. Żadnych egzotycznych wyborów — wszystko to narzędzia, na które natkniesz się w komercyjnych projektach .NET-owych.

  • .NET 6 / C# 10 — najnowsze LTS w momencie startu serii, top-level statements, minimal hosting, cała reszta nowinek.
  • Aplikacja konsolowa — celowo bez ASP.NET Core, bo chcę pokazać, że hosting generyczny (IHostBuilder) działa wszędzie, nie tylko w webówce.
  • Entity Framework Core — do bazy MySQL, z której wyciągamy firmy. Database-first albo code-first — zobaczysz w odcinku drugim.
  • Dependency Injection — wbudowany kontener z Microsoft.Extensions.DependencyInjection. Cały projekt pójdzie w konwencji serwisów rejestrowanych przez DI, bez żadnych statyków i new-ów w losowych miejscach.
  • IOptions + appsettings.json — żeby klucze do API, connection stringi i ustawienia nie wisiały jako stringi w kodzie.
  • HttpClient + IHttpClientFactory — do Google Places API i WordPress REST API. Pokażę, dlaczego new HttpClient() to pułapka.
  • Selenium WebDriver — bot, który klika w przeglądarce. Sam nigdy wcześniej tego nie używałem, więc uczymy się razem z dokumentacji.
  • WordPress REST API — endpoint /wp-json/wp/v2/posts plus autoryzacja tokenem Bearer.
  • Google Places API — Place Details, Find Place, Nearby Search.

Stack jest celowo "zwyczajny". Jak zrobisz tę aplikację, to w pracy przy enterprise'owych systemach nie zobaczysz nic fundamentalnie innego — będą to te same cegiełki, tylko w innym układzie.

Plan na 15 odcinków

Seria jest długa i otwarta — dochodzą nowe rzeczy, jak natrafiamy na ścianę. Ale szkielet wygląda tak:

#OdcinekTematy techniczne
0Opis projektu i rozkład jazdyArchitektura, plan działania
1Konfiguracja Entity FrameworkEF Core, migracje, MySQL
2Dependency Injection w konsolówceIServiceCollection, IHost, lifetime'y
3Generowanie klucza Google Places APIGoogle Cloud Console, billing, restrykcje
4Options i appsettings.jsonIOptions<T>, konfiguracja środowisk
5Integracja z Google Places APIHttpClient, DTO, deserializacja JSON
6Przegląd API WordPressaEndpointy, struktura REST
7Pobieranie Bearer Tokena z WPAuth, JWT, refresh flow
8Dodawanie postów przez WP APIPOST /wp-json, custom fields, kategorie
9Selenium — konfiguracja botaWebDriver, ChromeDriver, selektory
10Spinanie wszystkiego w całośćOrkiestracja modułów, end-to-end test
11Zaawansowane operacje z Google APIPaging, rate limiting, cache
12Zaawansowane integracje z WordPressemMedia upload, taksonomie, metadane
13Zaawansowane operacje na bazieTransakcje, bulk insert, performance
14Obsługa błędów z try/catchStrategie retry, Polly, logowanie

Celowo nie rozpisuję każdego odcinka na sztywno w excelu. W realnej pracy programisty i tak wylądujesz w sytuacji, której nie przewidział nikt z architektów. Lepiej nauczyć się reagować niż przewidywać.

Każdy z tych odcinków to osobny film na YouTubie, ale też osobny commit (albo gałąź) w repo, więc możesz iść razem ze mną krok po kroku, wgrywając kod w swoim tempie.

Dlaczego bot Selenium, skoro jest REST API

Ten fragment wymaga osobnego akapitu, bo ludzie pytają za każdym razem. WordPress REST API bez problemu doda ci post z ogłoszeniem — POST /wp-json/wp/v2/posts i jedziesz. Ale kiedy chcesz dodać opinię z oceną w gwiazdkach i dodatkowymi kategoriami (kontakt, cena, jakość wykonania, terminowość), okazuje się, że używana przez marketplace wtyczka nie wystawia tej części przez API. Gwiazdki trzeba kliknąć w UI.

Mamy dwie opcje: reverse-engineerować wtyczkę (tydzień pracy) albo napisać bota, który udaje zalogowanego użytkownika (dwa dni). Wybieramy bota, bo:

  1. Jest okazja, żeby nauczyć się Selenium w C# — umiejętność przydatna przy pisaniu testów E2E.
  2. Jest szybciej.
  3. Dostajesz bonus: prosty algorytm opiniowania, który z jednej oceny Google (np. 4.7) rozbija wynik na cztery kategorie. To ciekawy, mały problem algorytmiczny.

W pracy programisty bardzo często "głupsze" rozwiązanie wygrywa z "eleganckim", bo dowozi wartość biznesową szybciej. Ten bot to dokładnie taki przypadek.

Co dalej?

W następnym odcinku bierzemy się za Entity Framework Core — konfigurujemy DbContext, podpinamy się do MySQL-a i wyciągamy pierwsze rekordy firm. Od tej pory każdy odcinek zamyka się konkretnym kawałkiem działającego kodu, który commitujesz razem ze mną.

Jeżeli chcesz iść razem ze mną kod w kod, całość jest otwarta na GitHubie: github.com/jarmatys/dotnet-wordpress-importer. Forkuj, klonuj, eksperymentuj.

Masz pytania do architektury albo konkretnego etapu, który chciałbyś rozwinąć szerzej (np. sam Google API albo sam Selenium)? Pisz w komentarzach pod filmem — seria jest otwarta i spokojnie mogę wrzucić dodatkowe odcinki, jeśli zobaczę, że jakiś temat wali wam w oczy. To ma być tutorial o praktyce, a nie mój monolog.

Do zobaczenia w odcinku pierwszym. Trzymaj się.

Tagi:#course-dotnet-wordpress#dotnet#csharp#wordpress#api

Masz pytanie do tego wpisu?

Napisz do mnie — chętnie porozmawiam o szczegółach technicznych, albo o tym jak zastosować to u Ciebie w projekcie.