Przejdź do treści
21 lipca 202620 min czytania

Jak AI zmienia sposób pisania kodu

Jak AI zmienia sposób pisania kodu
Obraz wygenerowany lub zmodyfikowany przez AI
Jak AI wspiera programistów w generowaniu boilerplate’u, pracy z API i tworzeniu funkcjonalności. Praktyczne przykłady pracy z kodem w .NET.

Jak AI zmienia sposób pisania kodu#

Jeszcze kilka lat temu typowy dzień programisty często zaczynał się w bardzo podobny sposób: otwarcie edytora, utworzenie nowego pliku i powolne budowanie rozwiązania linijka po linijce. Trzeba było przypomnieć sobie składnię, zajrzeć do dokumentacji i sprawdzić przykłady w internecie.

Dopiero potem powstawała pierwsza działająca wersja kodu.

Dziś punkt startowy często wygląda inaczej. Narzędzia oparte na sztucznej inteligencji potrafią zaproponować szkic rozwiązania niemal natychmiast. Zamiast zaczynać od pustego pliku, możesz opisać problem i otrzymać wstępną implementację, którą następnie rozwijasz.

W praktyce oznacza to zmianę sposobu pracy. Zamiast pisać wszystko od zera, zaczynasz od propozycji, którą możesz poprawić, uprościć albo dopasować do architektury projektu.

Najbardziej widać to przy zadaniach powtarzalnych lub dobrze zdefiniowanych. Generowanie prostych metod, przekształcanie danych, operacje na kolekcjach czy tworzenie podstawowych klas to zadania, w których modele AI często sprawdzają się szczególnie dobrze.

Wyobraź sobie sytuację, w której potrzebujesz napisać niewielką funkcję przetwarzającą dane z listy. Jeszcze niedawno najczęściej robiło się to ręcznie, czasem sprawdzając dokumentację lub przykłady w internecie.

Dziś możesz po prostu opisać oczekiwany efekt: „przefiltruj listę produktów i zwróć tylko te powyżej określonej ceny”. W odpowiedzi otrzymujesz szkic implementacji.

To nie tylko oszczędność czasu. Zmienia się również sposób myślenia o pracy z kodem.

Zamiast koncentrować się na każdej pojedynczej instrukcji, łatwiej skupić się na logice rozwiązania i strukturze aplikacji.

Spójrzmy na bardzo prosty przykład. Załóżmy, że w aplikacji masz klasę reprezentującą produkt oraz serwis wykonujący operacje na liście produktów.

Jednym z zadań może być zwrócenie tylko tych produktów, których cena przekracza określoną wartość.

AI może zaproponować kod podobny do tego:

Snippet
csharp
using System;
using System.Collections.Generic;
using System.Linq;
public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}
public class ProductService
{
    public List<Product> GetExpensiveProducts(List<Product> products, decimal minPrice)
    {
        return products
            .Where(p => p.Price >= minPrice)
            .ToList();
    }
}

Dla doświadczonego programisty taki fragment jest oczywisty. Jednak możliwość wygenerowania go bardzo szybko ma znaczenie, szczególnie gdy w projekcie pojawia się wiele podobnych fragmentów.

Oczywiście wygenerowany kod rzadko jest idealny od razu. Nazwy zmiennych mogą nie pasować do konwencji projektu. Metoda może znajdować się w niewłaściwym miejscu architektury.

Samo rozwiązanie bywa też bardziej rozbudowane niż to konieczne. Dlatego wygenerowany kod najlepiej traktować przede wszystkim jako punkt wyjścia.

Analizujesz go, upraszczasz, dopasowujesz do stylu projektu i integrujesz z resztą systemu.

AI pomaga także w sytuacjach, gdy pamiętasz ogólny pomysł rozwiązania, ale nie pamiętasz dokładnej składni. Zamiast przerywać pracę i szukać odpowiedzi w dokumentacji, możesz szybko uzyskać przykład użycia LINQ, konfiguracji klienta HTTP czy fragment kodu przekształcającego dane między strukturami.

Dzięki temu praca staje się bardziej płynna. Rzadziej musisz przerywać pisanie kodu i przełączać się między różnymi źródłami informacji.

Zmienia się również rytm samego programowania. Dawniej proces był bardziej liniowy: plan, implementacja, poprawki.

Dziś często przypomina serię krótkich iteracji. Najpierw powstaje szkic rozwiązania, potem kolejne drobne poprawki — uproszczenie kodu, dodanie walidacji, obsługa błędów czy zmiana struktury metody.

Po kilku takich krokach powstaje rozwiązanie znacznie bliższe temu, czego faktycznie potrzebujesz. Praca zaczyna przypominać dialog: wyznaczasz kierunek, a narzędzie pomaga szybko sprawdzać różne warianty implementacji.

Nie oznacza to jednak, że wszystko działa bezbłędnie. Modele potrafią generować nieoptymalny kod, popełniać błędy lub proponować rozwiązania niedopasowane do struktury projektu.

Dlatego wciąż kluczowa pozostaje umiejętność czytania i oceniania kodu.

Właśnie tutaj doświadczenie programisty ma ogromne znaczenie. Jeśli dobrze znasz język programowania, wzorce projektowe i architekturę systemów, łatwiej jest szybko ocenić wygenerowaną propozycję i wprowadzić potrzebne poprawki.

W praktyce prowadzi to do wyraźnej zmiany w codziennej pracy. Coraz mniej czasu poświęcasz na mechaniczne pisanie oczywistych fragmentów kodu.

Coraz więcej uwagi trafia na projektowanie rozwiązań, analizę problemów i podejmowanie decyzji technicznych.

Punkt ciężkości przesuwa się więc z samego pisania kodu na jego świadome kształtowanie — z ręcznego tworzenia każdej linijki na prowadzenie procesu, w którym narzędzia pomagają szybciej dojść do dobrego rozwiązania.

Generowanie boilerplate’u i struktury projektu#

Jednym z miejsc, w których generowanie kodu przez AI naprawdę robi różnicę, jest sam początek projektu. Każdy, kto pracował przy kilku aplikacjach .NET, dobrze zna ten etap: zanim pojawi się jakakolwiek logika biznesowa, trzeba przygotować sporą ilość powtarzalnej infrastruktury. Tworzenie katalogów, konfiguracji, podstawowych klas, rejestracja usług czy konfiguracja środowiska — to wszystko jest konieczne, ale rzadko bywa szczególnie inspirujące.

Właśnie tutaj AI często potrafi znacząco przyspieszyć pracę. Zamiast ręcznie budować strukturę projektu od zera, można wygenerować gotowy boilerplate (czyli podstawowy kod startowy projektu, powtarzający się w wielu aplikacjach) oraz szkielet aplikacji. Programista nadal podejmuje wszystkie kluczowe decyzje architektoniczne, ale nie musi wykonywać dziesiątek drobnych, powtarzalnych kroków.

Dlaczego boilerplate zabiera tyle czasu#

Na pierwszy rzut oka stworzenie nowego projektu .NET wydaje się proste. W końcu polecenie dotnet new webapi generuje działającą aplikację w kilka chwil. Problem polega na tym, że prawdziwe projekty rzadko korzystają z tej struktury w czystej postaci.

Zazwyczaj bardzo szybko pojawiają się dodatkowe wymagania:

  • podział projektu na warstwy
  • oddzielenie logiki domenowej od infrastruktury
  • wprowadzenie serwisów aplikacyjnych
  • konfiguracja dependency injection (mechanizmu wstrzykiwania zależności między klasami)
  • przygotowanie DTO (Data Transfer Object — obiekty służące do przenoszenia danych między warstwami aplikacji)
  • konfiguracja plików appsettings
  • dodanie podstawowych testów

Każdy z tych elementów sam w sobie jest prosty, ale razem tworzą sporą ilość kodu startowego. Co więcej, jest to kod, który wygląda niemal identycznie w wielu projektach.

Dlatego generowanie boilerplate’u jest szczególnie dobrym zadaniem dla modeli AI. Nie wymaga złożonego rozwiązywania problemów — wystarczy przygotować spójny, poprawny szkielet zgodny z wybraną architekturą.

Generowanie struktury warstwowej#

Dobrym przykładem jest popularna architektura warstwowa lub jej odmiana znana jako Clean Architecture (podejście architektoniczne zakładające wyraźne oddzielenie logiki biznesowej od infrastruktury i szczegółów technicznych). W wielu projektach pojawia się bardzo podobny podział katalogów:

  • Domain – logika domenowa, czyli model biznesowy aplikacji
  • Application – przypadki użycia i serwisy aplikacyjne
  • Infrastructure – integracje z bazą danych i zewnętrznymi systemami
  • API – warstwa komunikacji HTTP udostępniająca endpointy aplikacji

Zamiast ręcznie tworzyć te katalogi i podstawowe pliki, można poprosić AI o wygenerowanie przykładowej struktury projektu wraz z minimalnymi klasami startowymi. W praktyce często wygląda to tak, że model przygotowuje:

  • strukturę katalogów
  • podstawowe interfejsy
  • przykładowe serwisy
  • konfigurację DI (dependency injection)
  • kontrolery

Taki zestaw daje już działający punkt startowy, który można uruchomić i dalej rozwijać.

Minimalny punkt startowy aplikacji#

Dobrym przykładem jest prosty szkielet aplikacji ASP.NET Core. Minimalny plik startowy może wyglądać następująco:

Snippet
csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

Ten fragment nie zawiera jeszcze żadnej logiki biznesowej, ale tworzy działającą aplikację HTTP z kontrolerami oraz dokumentacją generowaną przez Swagger (narzędzie automatycznie opisujące i dokumentujące API).

Taki fundament można później stopniowo rozbudowywać.

Model AI zazwyczaj potrafi wygenerować podobny kod bardzo szybko, a także rozszerzyć go o dodatkowe elementy, na przykład:

  • konfigurację CORS (Cross‑Origin Resource Sharing — mechanizm kontrolujący, które domeny mogą wykonywać zapytania do API)
  • middleware (komponenty pośrednie przetwarzające każde żądanie HTTP w aplikacji)
  • integrację z bazą danych
  • rejestrację własnych serwisów

Dzięki temu pierwsza wersja projektu powstaje znacznie szybciej.

Generowanie prostych serwisów#

Kolejnym naturalnym krokiem jest przygotowanie podstawowych klas aplikacyjnych. AI zazwyczaj dobrze radzi sobie z tworzeniem prostych serwisów, które można później rozbudować.

Przykładowy serwis aplikacyjny może wyglądać tak:

Snippet
csharp
namespace Application.Services;
public class UserService
{
    public string GetWelcomeMessage(string name)
    {
        return $"Witaj, {name}!";
    }
}

To oczywiście bardzo prosty przykład, ale dobrze pokazuje ideę. AI proponuje strukturę klasy, nazewnictwo oraz podstawową implementację. Programista może później dodać:

  • dostęp do repozytorium
  • walidację danych
  • logowanie
  • obsługę wyjątków

Najważniejsze jest to, że nie trzeba zaczynać od pustego pliku.

Generowanie kontrolerów#

Podobnie wygląda sytuacja z kontrolerami. W wielu projektach kontroler HTTP ma bardzo przewidywalną strukturę: wstrzyknięcie serwisu, kilka metod odpowiadających poszczególnym endpointom (czyli adresom API obsługującym konkretne operacje) oraz mapowanie danych.

AI potrafi wygenerować taki kontroler w bardzo krótkim czasie. Na przykład:

Snippet
csharp
using Microsoft.AspNetCore.Mvc;
using Application.Services;
namespace API.Controllers;
[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
    private readonly UserService _userService;
    public UsersController(UserService userService)
    {
        _userService = userService;
    }
    [HttpGet("welcome")]
    public IActionResult GetWelcomeMessage(string name)
    {
        var message = _userService.GetWelcomeMessage(name);
        return Ok(message);
    }
}

Taki kontroler można oczywiście dalej rozwijać, ale najważniejsze elementy są już na miejscu: routing, dependency injection oraz podstawowa struktura endpointu.

Spójność w projekcie#

Jedną z mniej oczywistych zalet korzystania z AI przy generowaniu boilerplate’u jest spójność. Kiedy wiele osób pracuje nad projektem, często pojawiają się drobne różnice w stylu:

  • różne nazwy klas
  • inne nazwy katalogów
  • różne sposoby wstrzykiwania zależności

Jeśli struktura projektu powstaje według jednego wzorca, łatwiej utrzymać jednolity styl kodu. AI może w takim przypadku pełnić rolę swoistego generatora konwencji, który powtarza ten sam schemat w wielu miejscach.

Oczywiście nie oznacza to, że wygenerowany kod powinien być przyjmowany bezrefleksyjnie. Zawsze warto go przejrzeć i dopasować do standardów zespołu. Jednak punkt wyjścia jest już gotowy.

Generowanie konfiguracji#

Modele językowe radzą sobie również dobrze z generowaniem konfiguracji aplikacji. Dotyczy to między innymi:

  • plików appsettings.json
  • klas konfiguracji
  • mapowania sekcji konfiguracji na obiekty
  • konfiguracji logowania

Przykładowy fragment appsettings.json może wyglądać tak:

Snippet
json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=SampleDb;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Do tego można wygenerować klasę reprezentującą konfigurację:

Snippet
csharp
namespace Infrastructure.Configuration;
public class DatabaseOptions
{
    public string ConnectionString { get; set; } = string.Empty;
}

Takie drobne elementy zwykle nie są trudne do napisania, ale jest ich dużo. Automatyzacja ich tworzenia znacząco skraca czas przygotowania projektu.

Co warto generować, a czego nie#

Najlepsze rezultaty osiąga się wtedy, gdy AI generuje kod powtarzalny i przewidywalny. Do tej kategorii należą między innymi:

  • struktura projektu
  • podstawowe klasy i interfejsy
  • DTO
  • kontrolery
  • konfiguracja

Znacznie ostrożniej należy podchodzić do generowania złożonej logiki biznesowej. W takich przypadkach AI może pomóc w przygotowaniu szkicu rozwiązania, ale ostateczna implementacja powinna zostać dokładnie przeanalizowana przez programistę.

Szybszy start projektu#

W praktyce oznacza to jedną bardzo konkretną zmianę w sposobie pracy. Początek projektu przestaje być długą serią mechanicznych czynności.

Zamiast spędzać pierwsze godziny na tworzeniu katalogów, plików i podstawowych klas, można wygenerować gotowy szkielet aplikacji w krótkim czasie. Następnie wystarczy go przejrzeć, dopasować do potrzeb projektu i zacząć pracę nad właściwymi problemami.

To przesuwa uwagę programisty tam, gdzie jest naprawdę potrzebna: na decyzje architektoniczne, model domenowy i logikę biznesową. Boilerplate przestaje być przeszkodą, a staje się szybkim, niemal automatycznym krokiem na drodze do działającej aplikacji.

Implementacja prostych funkcjonalności z pomocą AI#

Po przygotowaniu podstawowego szkieletu projektu przychodzi moment, w którym aplikacja zaczyna naprawdę „żyć”. Struktura katalogów istnieje, główne klasy są na miejscu, projekt się kompiluje — ale w wielu miejscach wciąż brakuje właściwej logiki. To właśnie etap, w którym programista zaczyna dodawać niewielkie fragmenty funkcjonalności: filtrowanie danych, proste obliczenia, transformacje obiektów czy pomocnicze metody.

W takich zadaniach narzędzia AI okazują się szczególnie przydatne.

Zamiast każdorazowo pisać od zera powtarzalne fragmenty kodu, można poprosić model o przygotowanie konkretnej metody lub krótkiego fragmentu logiki. Wystarczy krótki opis problemu, aby otrzymać propozycję implementacji, którą następnie można dopasować do kontekstu projektu. Taki kod rzadko trafia do repozytorium bez zmian — ale bardzo często stanowi wygodny punkt startowy.

Dzięki temu programista może skupić się bardziej na architekturze i logice biznesowej, zamiast tracić czas na powtarzalne implementacje.

Generowanie niewielkich metod#

Jednym z najczęstszych zastosowań AI w codziennej pracy jest generowanie małych metod pomocniczych. W typowej aplikacji pojawia się ich naprawdę dużo. Mogą odpowiadać za filtrowanie danych, przetwarzanie kolekcji, obliczanie wartości lub przygotowanie wyników do dalszego użycia.

W środowisku .NET bardzo często wykorzystuje się do tego LINQ, który pozwala w czytelny sposób operować na kolekcjach. AI potrafi zazwyczaj zaproponować rozwiązania zgodne z tym stylem, co dodatkowo zwiększa czytelność kodu.

Przykładowo, wyobraźmy sobie prosty model zamówienia:

Snippet
csharp
public class Order
{
    public decimal Price { get; set; }
    public bool IsCompleted { get; set; }
}

Załóżmy, że chcemy obliczyć łączną wartość zamówień, które zostały zakończone. Jest to typowy fragment logiki pojawiający się w systemach sprzedażowych, raportach lub panelach administracyjnych.

Jedna z możliwych implementacji takiej funkcji może wyglądać następująco:

Snippet
csharp
public static decimal CalculateCompletedOrdersValue(List<Order> orders)
{
    return orders
        .Where(o => o.IsCompleted)
        .Sum(o => o.Price);
}

Kod jest krótki, czytelny i robi dokładnie to, czego oczekujemy:

  • filtruje zamówienia oznaczone jako zakończone,
  • następnie sumuje ich ceny,
  • zwraca wynik jako pojedynczą wartość.

Tego typu metoda może zostać wykorzystana w wielu miejscach aplikacji: w serwisach biznesowych, w kontrolerach API, w logice raportów albo podczas przygotowywania danych dla interfejsu użytkownika.

W praktyce przygotowanie takiej funkcji przy wsparciu AI zajmuje chwilę. Programista opisuje oczekiwane zachowanie, a model proponuje jedną z typowych implementacji, którą można od razu przejrzeć i ewentualnie dostosować.

Dopasowanie wygenerowanego kodu#

Warto jednak pamiętać o jednej istotnej zasadzie: kod wygenerowany przez AI należy traktować jako propozycję, a nie jako gotowe rozwiązanie.

Modele językowe bardzo dobrze radzą sobie z rozpoznawaniem wzorców i typowych sposobów rozwiązywania problemów, ale nie znają szczegółów konkretnego projektu. Nie wiedzą na przykład:

  • jakie konwencje nazewnicze obowiązują w repozytorium,
  • czy projekt korzysta z konkretnych bibliotek,
  • czy pewne operacje powinny być wykonywane asynchronicznie,
  • czy istnieją już metody realizujące podobną funkcjonalność.

Dlatego po wygenerowaniu kodu warto poświęcić chwilę na jego przejrzenie i dostosowanie. W praktyce oznacza to zazwyczaj kilka prostych kroków:

  • dopasowanie nazw klas i właściwości do istniejącego modelu domenowego,
  • sprawdzenie typów danych,
  • upewnienie się, że metoda pasuje do stylu kodu w projekcie,
  • ewentualne uproszczenie lub refaktoryzację.

Najczęściej taka korekta zajmuje kilkanaście sekund, a efekt końcowy jest w pełni zgodny z wymaganiami projektu.

Proste przetwarzanie danych#

Drugim bardzo częstym zastosowaniem AI jest transformacja danych. W aplikacjach biznesowych niezwykle często zachodzi potrzeba konwersji jednego modelu do innego. Przykładem może być mapowanie:

  • encji bazy danych na model API,
  • modelu domenowego na DTO,
  • danych wejściowych na obiekt używany w logice biznesowej.

AI radzi sobie z takimi zadaniami bardzo sprawnie, szczególnie gdy struktura danych jest stosunkowo prosta.

Wyobraźmy sobie na przykład, że chcemy przekształcić listę zamówień w uproszczony model wykorzystywany przez warstwę prezentacji.

Snippet
csharp
public class OrderSummary
{
    public decimal Price { get; set; }
    public bool Completed { get; set; }
}

W takiej sytuacji potrzebna jest metoda, która zamieni jeden typ obiektu na drugi. Przykładowa implementacja może wyglądać następująco:

Snippet
csharp
public static List<OrderSummary> MapOrders(List<Order> orders)
{
    return orders
        .Select(o => new OrderSummary
        {
            Price = o.Price,
            Completed = o.IsCompleted
        })
        .ToList();
}

To bardzo typowy fragment kodu. W wielu projektach powstają dziesiątki podobnych metod, które różnią się jedynie strukturą modeli.

Zamiast tworzyć każdą z nich ręcznie, można po prostu opisać oczekiwany rezultat, na przykład:

„Wygeneruj metodę mapującą listę Order na listę OrderSummary przy użyciu LINQ.”

Model zwykle zaproponuje poprawną strukturę metody, którą następnie można dopasować do konwencji projektu.

Szybsze eksperymentowanie z logiką#

Kolejną zaletą korzystania z AI jest możliwość szybkiego eksperymentowania z różnymi wariantami implementacji.

Czasami istnieje kilka sposobów rozwiązania tego samego problemu. Można użyć klasycznej pętli foreach, można zastosować LINQ, a w innych przypadkach lepszym rozwiązaniem będzie przygotowanie osobnej klasy serwisowej.

Zamiast zastanawiać się nad każdym wariantem od zera, można poprosić AI o kilka alternatyw. Dzięki temu łatwiej porównać różne podejścia i wybrać najbardziej czytelne lub najbardziej wydajne.

Taki sposób pracy jest szczególnie pomocny podczas:

  • szybkiego prototypowania funkcjonalności,
  • eksplorowania nowych bibliotek,
  • uczenia się mniej znanych elementów frameworka.

AI działa wtedy trochę jak dodatkowy programista, który podsuwa pomysły i przykłady implementacji.

Na co warto uważać#

Mimo wielu zalet, korzystanie z AI w programowaniu wymaga zdrowego rozsądku. Modele potrafią generować kod, który wygląda poprawnie, ale w praktyce zawiera drobne błędy lub niepotrzebną złożoność.

Dlatego przed włączeniem takiego fragmentu do projektu warto sprawdzić kilka rzeczy.

Po pierwsze, czy logika rzeczywiście robi to, czego oczekujemy. Nawet niewielka pomyłka w warunku filtrowania może prowadzić do trudnych do wykrycia błędów.

Po drugie, czy operacje na kolekcjach są wykonywane efektywnie. Czasami AI może zaproponować kilka następujących po sobie operacji LINQ, które można łatwo uprościć.

Po trzecie, czy kod pozostaje spójny z resztą projektu. Jeśli w projekcie obowiązuje określony styl pisania metod lub konwencja nazewnicza, warto się jej trzymać.

AI jako wsparcie, nie zastępstwo#

Najlepsze efekty pojawiają się wtedy, gdy traktujemy AI jako narzędzie wspierające codzienną pracę, a nie jako system podejmujący decyzje za programistę.

Modele świetnie radzą sobie z generowaniem powtarzalnych fragmentów kodu, proponowaniem przykładów oraz przyspieszaniem drobnych implementacji. Nadal jednak to programista odpowiada za architekturę aplikacji, poprawność logiki biznesowej i jakość końcowego rozwiązania.

W praktyce oznacza to prostą zasadę: AI może przygotować pierwszy szkic, ale ostateczna wersja kodu zawsze powinna przejść przez świadomą ocenę i ewentualną poprawę.

Takie podejście pozwala wykorzystać największą zaletę modeli językowych — szybkość generowania kodu — jednocześnie zachowując pełną kontrolę nad projektem.

Praca z API i integracjami przy wsparciu modeli AI#

Integracja z zewnętrznymi usługami to codzienność w pracy wielu programistów. Niezależnie od tego, czy chodzi o system płatności, API pogodowe, system CRM czy wewnętrzny mikroserwis, aplikacje bardzo często komunikują się z innymi systemami przez HTTP. Właśnie w takich zadaniach modele AI często okazują się szczególnie pomocne.

Duża część kodu integracyjnego ma dość powtarzalny charakter. Tworzenie klientów API, modeli danych (DTO – Data Transfer Object, czyli obiektów przenoszących dane między systemami), obsługa zapytań HTTP czy przetwarzanie odpowiedzi zazwyczaj wygląda bardzo podobnie w wielu projektach.

Dlatego AI często dość dobrze radzi sobie z przygotowaniem pierwszej wersji takiego kodu. Programista może wtedy skupić się bardziej na logice biznesowej i architekturze, zamiast ręcznie pisać wiele niemal identycznych klas.

W praktyce współpraca z modelem zwykle zaczyna się od prostego opisu integracji. W promptcie można podać na przykład:

  • adres endpointu
  • metodę HTTP (GET, POST, PUT, DELETE)
  • parametry zapytania
  • strukturę odpowiedzi

Na tej podstawie AI często jest w stanie wygenerować szkic klienta API wraz z modelami danych. Taki kod zazwyczaj nie jest jeszcze gotowy do użycia w środowisku produkcyjnym, ale bardzo często stanowi wygodny punkt wyjścia, który można dalej dopracować.

Generowanie prostego klienta HTTP#

Załóżmy prostą sytuację: aplikacja ma pobierać dane z zewnętrznego API. Potrzebujemy więc komponentu, który wyśle zapytanie HTTP, odbierze odpowiedź i zamieni ją na obiekty używane w kodzie.

W aplikacjach .NET najczęściej wykorzystuje się do tego klasę HttpClient. W połączeniu z biblioteką System.Text.Json pozwala ona w prosty sposób pobierać dane z API i zamieniać odpowiedź JSON na obiekty C#.

W takich przypadkach AI często potrafi przygotować kompletną klasę klienta API. Zazwyczaj zawiera ona kilka podstawowych kroków:

  • wysłanie zapytania HTTP
  • sprawdzenie kodu odpowiedzi
  • odczytanie treści odpowiedzi
  • deserializację JSON do obiektu

Przykładowa implementacja może wyglądać tak:

Snippet
csharp
using System.Net.Http;
using System.Text.Json;
public class WeatherClient
{
    private readonly HttpClient _httpClient;
    public WeatherClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
    public async Task<WeatherDto?> GetWeatherAsync(string city)
    {
        var response = await _httpClient.GetAsync($"/api/weather?city={city}");
        if (!response.IsSuccessStatusCode)
        {
            return null;
        }
        var json = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<WeatherDto>(json);
    }
}
public class WeatherDto
{
    public string City { get; set; }
    public decimal Temperature { get; set; }
}

To dość typowy przykład kodu integracyjnego. Zawiera wysłanie zapytania HTTP, odczyt odpowiedzi oraz zamianę danych JSON na obiekt C#.

W realnym projekcie taka implementacja zazwyczaj jest dopiero początkiem. Programista często rozszerza ją o obsługę wyjątków, logowanie czy konfigurację adresu bazowego API.

Wykorzystanie Dependency Injection#

Kolejnym krokiem jest zwykle poprawna konfiguracja klienta HTTP w aplikacji. W nowoczesnych projektach .NET najczęściej robi się to przy pomocy mechanizmu Dependency Injection (czyli wstrzykiwania zależności między klasami).

Dzięki temu konfiguracja klienta HTTP znajduje się w jednym miejscu, a sama klasa klienta pozostaje stosunkowo prosta.

W praktyce HttpClient często rejestrowany jest w kontenerze usług aplikacji. Można wtedy ustawić na przykład adres bazowy API, nagłówki lub limity czasu oczekiwania.

AI często może pomóc również w wygenerowaniu takiej konfiguracji. Przykład w pliku Program.cs może wyglądać następująco:

Snippet
csharp
builder.Services.AddHttpClient<WeatherClient>(client =>
{
    client.BaseAddress = new Uri("https://example.com");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
});

Dzięki temu klasa WeatherClient otrzymuje już skonfigurowany obiekt HttpClient. Takie podejście zazwyczaj poprawia czytelność kodu i ułatwia testowanie aplikacji.

Mapowanie odpowiedzi API#

W praktyce dane zwracane przez API rzadko trafiają bezpośrednio do logiki biznesowej aplikacji. Zewnętrzny system może zwracać więcej pól niż potrzebujemy albo używać innego nazewnictwa.

Dlatego często wprowadza się osobne obiekty DTO (Data Transfer Object), które reprezentują surową odpowiedź API.

AI zazwyczaj dość dobrze radzi sobie z generowaniem takich klas. Wystarczy wkleić przykładową odpowiedź JSON i poprosić o przygotowanie odpowiedniego modelu C#.

Przykładowa odpowiedź API może wyglądać tak:

Snippet
json
{
  "city": "Warsaw",
  "temperature": 21.5,
  "humidity": 60
}

Na podstawie takiego fragmentu model AI często potrafi wygenerować klasę DTO, którą następnie wykorzystamy w kliencie API.

W wielu projektach kolejnym krokiem jest mapowanie DTO na model domenowy aplikacji. Model domenowy zawiera tylko te dane, które są rzeczywiście potrzebne w logice biznesowej.

Przykładowe mapowanie może wyglądać tak:

Snippet
csharp
public class Weather
{
    public string City { get; }
    public decimal Temperature { get; }
    public Weather(string city, decimal temperature)
    {
        City = city;
        Temperature = temperature;
    }
}
public static class WeatherMapper
{
    public static Weather ToDomain(WeatherDto dto)
    {
        return new Weather(dto.City, dto.Temperature);
    }
}

AI często potrafi wygenerować takie mapowanie automatycznie, szczególnie gdy liczba pól w modelu jest większa. Dzięki temu łatwiej utrzymać wyraźne oddzielenie danych zewnętrznych od logiki domenowej.

Obsługa błędów i nieoczekiwanych odpowiedzi#

Na pierwszy rzut oka integracja z API może wydawać się prosta: wysyłamy zapytanie i odbieramy odpowiedź. W praktyce jednak zewnętrzne systemy nie zawsze działają idealnie.

API może zwracać błędy, zmieniać strukturę danych albo czasowo przestać odpowiadać. Dlatego w kliencie API zazwyczaj warto uwzględnić podstawowe mechanizmy obsługi takich sytuacji.

Najczęściej obejmuje to:

  • sprawdzanie kodów statusu HTTP
  • obsługę wyjątków sieciowych
  • logowanie błędów
  • walidację danych z odpowiedzi

AI często może pomóc wygenerować bardziej rozbudowaną wersję metody, która uwzględnia takie scenariusze. Na przykład poprzez dodanie obsługi HttpRequestException albo sprawdzanie poprawności deserializacji.

W większych projektach często wykorzystuje się również bibliotekę Polly, która umożliwia implementację mechanizmów takich jak retry (ponawianie zapytań), circuit breaker (czasowe blokowanie zapytań po serii błędów) czy kontrola timeoutów. Modele AI zazwyczaj potrafią przygotować przykładową konfigurację takich mechanizmów dla HttpClient.

Generowanie kodu na podstawie dokumentacji API#

Czasami dokumentacja API jest bardzo szczegółowa, ale samo przygotowanie klienta nadal zajmuje sporo czasu. Właśnie tutaj AI często bywa szczególnie przydatne.

Jeśli API posiada dokumentację w formacie OpenAPI, Swagger albo nawet zwykły opis endpointów, można wkleić jej fragment do promptu i poprosić model o przygotowanie kodu klienta.

Wystarczy przekazać między innymi:

  • adres endpointu
  • parametry zapytania
  • przykładową odpowiedź
  • wymagane nagłówki

Na tej podstawie AI często potrafi wygenerować:

  • klasę klienta
  • modele DTO
  • metody wysyłające zapytania

Takie podejście bywa szczególnie pomocne na początku projektu, gdy trzeba stosunkowo szybko przygotować podstawową komunikację z kilkoma usługami zewnętrznymi.

Przyspieszanie refaktoryzacji integracji#

AI może być pomocne nie tylko przy tworzeniu nowych integracji. Równie dobrze często sprawdza się podczas porządkowania starszego kodu.

W wielu projektach klienci API powstają w różnych momentach i często mają niespójną strukturę. Zdarza się też, że zawierają sporo powtarzalnego kodu.

W takiej sytuacji można wkleić fragment istniejącej implementacji i poprosić model o:

  • uproszczenie struktury kodu
  • wydzielenie warstwy mapowania
  • poprawę obsługi błędów
  • dostosowanie kodu do aktualnych konwencji .NET

Dzięki temu często łatwiej stopniowo modernizować starsze fragmenty systemu bez konieczności przepisywania wszystkiego od początku.

Dlaczego nadal potrzebna jest weryfikacja kodu#

Choć modele AI często dobrze radzą sobie z generowaniem kodu integracyjnego, wygenerowane fragmenty nie powinny być traktowane jako gotowe rozwiązania produkcyjne. Model nie zna pełnego kontekstu systemu ani standardów przyjętych w danym zespole.

Dlatego przed wykorzystaniem takiego kodu w aplikacji zwykle warto sprawdzić kilka rzeczy:

  • czy modele danych dokładnie odpowiadają rzeczywistej odpowiedzi API
  • czy obsłużone są wszystkie istotne scenariusze błędów
  • czy kod jest zgodny z konwencjami projektu
  • czy nie brakuje logowania, walidacji lub testów

Najlepiej traktować AI jako bardzo szybki generator pierwszej wersji rozwiązania. Programista nadal odpowiada za architekturę systemu, jakość implementacji i bezpieczeństwo integracji.

Podsumowanie#

Integracja z API to jeden z obszarów, w których modele AI często przynoszą szybkie i widoczne korzyści. Generowanie klientów HTTP, modeli DTO czy podstawowej obsługi odpowiedzi to zadania powtarzalne, ale wymagające precyzji.

Dzięki AI można zwykle wyraźnie skrócić czas potrzebny na przygotowanie takiego kodu. Wystarczy opisać endpoint i strukturę danych, aby otrzymać działający szkic implementacji.

Najlepsze rezultaty często pojawiają się wtedy, gdy traktujemy AI jako narzędzie wspierające proces tworzenia oprogramowania. Model może szybko przygotować bazowy kod, zasugerować strukturę klas lub pomóc przeanalizować dokumentację API.

Ostateczna odpowiedzialność za architekturę, jakość i bezpieczeństwo implementacji nadal pozostaje jednak po stronie programisty. W praktyce dobrze sprawdza się podejście iteracyjne: najpierw prosty klient API, a następnie stopniowe rozszerzanie go o obsługę błędów, logowanie, testy oraz dopasowanie do standardów projektu.

To jednak dopiero początek pracy z kodem generowanym przez AI. Samo wygenerowanie rozwiązania rzadko jest końcem procesu — znacznie częściej staje się punktem wyjścia do dalszego dopracowywania, testowania i przekształcania go w coś naprawdę produkcyjnego. Właśnie w tym miejscu zaczyna się najbardziej praktyczny etap współpracy z modelem: iteracyjne doprecyzowywanie i refaktoryzacja tego, co zostało wygenerowane.

Udostępnij
Zachowaj link lub przekaż artykuł dalej.
Newsletter

Dołącz do naszego stada

Krótko, konkretnie i bez szumu. Najnowsze artykuły oraz praktyczne materiały trafiają prosto do skrzynki.

Zapis oznacza akceptację Polityki prywatności.