KoderKoder.ai
CennikDla firmEdukacjaDla inwestorów
Zaloguj sięRozpocznij

Produkt

CennikDla firmDla inwestorów

Zasoby

Skontaktuj się z namiPomoc technicznaEdukacjaBlog

Informacje prawne

Polityka prywatnościWarunki użytkowaniaBezpieczeństwoZasady dopuszczalnego użytkowaniaZgłoś nadużycie

Social media

LinkedInTwitter
Koder.ai
Język

© 2026 Koder.ai. Wszelkie prawa zastrzeżone.

Strona główna›Blog›Claude Code do tworzenia szkieletu API w Go: spójne handlery i serwisy
01 sty 2026·6 min

Claude Code do tworzenia szkieletu API w Go: spójne handlery i serwisy

Claude Code do tworzenia szkieletu API w Go: zdefiniuj czysty wzorzec handler-service-error raz, a potem generuj nowe endpointy, które pozostaną spójne w całym API Go.

Claude Code do tworzenia szkieletu API w Go: spójne handlery i serwisy

Dlaczego API w Go robią się nieporządne, jeśli wzorce nie są ustalone wcześnie

API w Go zwykle zaczynają czysto: kilka endpointów, jedna lub dwie osoby, a wszystko żyje w głowach. Potem API rośnie, funkcje są wypuszczane pod presją i wkradają się małe różnice. Każda z nich wydaje się niegroźna, ale razem spowalniają każdą przyszłą zmianę.

Typowy przykład: jeden handler dekoduje JSON do struktury i zwraca 400 z pomocnym komunikatem, inny zwraca 422 o innym kształcie, a trzeci loguje błędy w innym formacie. Nic z tego nie łamie kompilacji. Po prostu powoduje ciągłe podejmowanie decyzji i drobne przeróbki za każdym razem, gdy dodajesz coś nowego.

Bałagan odczujesz w miejscach takich jak:

  • Różne ciała błędów między endpointami, więc klienci potrzebują wyjątków.
  • Serwisy, które czasem zwracają surowe błędy bazy danych, a czasem „przyjazne”.
  • Dryf nazewniczy (CreateUser, AddUser, RegisterUser), który utrudnia wyszukiwanie.
  • Walidacja przenoszona w różne miejsca, przez co te same błędy wracają.

„Scaffolding” tutaj oznacza powtarzalny szablon dla nowej pracy: gdzie umieszczać kod, co robi każda warstwa i jak wyglądają odpowiedzi. Chodzi mniej o generowanie dużej ilości kodu, a bardziej o zamknięcie spójnego kształtu.

Narzędzia jak Claude mogą pomóc szybko zaszkieletować nowe endpointy, ale pozostają użyteczne tylko wtedy, gdy traktujesz wzorzec jak regułę. Ty definiujesz reguły, przeglądasz każdy diff i uruchamiasz testy. Model wypełnia standardowe części; nie może redefiniować twojej architektury.

Wybierz jeden podział warstw: handler, service i dostęp do danych

API w Go łatwo się rozwija, gdy każde żądanie podąża tą samą ścieżką. Zanim zaczniesz generować endpointy, wybierz jeden podział warstw i trzymaj się go.

Odpowiedzialności, prosto

Zadaniem handlera jest tylko HTTP: odczytać żądanie, wywołać service i zapisać odpowiedź. Nie powinien zawierać reguł biznesowych, SQL ani „tylko tego jednego specjalnego przypadku”.

Service odpowiada za przypadek użycia: reguły biznesowe, decyzje i orkiestrację między repozytoriami lub wywołaniami zewnętrznymi. Nie powinien znać spraw HTTP, jak kody statusu, nagłówki czy sposób renderowania błędów.

Dostęp do danych (repository/store) odpowiada za szczegóły trwałości. Tłumaczy intencje service na SQL/zapytania/transakcje. Nie powinien wymuszać reguł biznesowych poza podstawową integralnością danych ani kształtować odpowiedzi API.

Lista kontrolna separacji, praktyczna:

  • Handler: parsuj input, wywołaj service, mapuj błędy na HTTP, zapisz JSON
  • Service: stosuj reguły biznesowe, wywołuj repo, zwracaj wyniki domenowe lub typowane błędy
  • Dostęp do danych: wykonuj zapytania, mapuj wiersze na struktury, zwracaj błędy magazynu
  • Wspólne: wspólne typy błędów i helpery odpowiedzi
  • Żadna warstwa nie pomija innej (handler nigdy nie wywołuje repo bezpośrednio)

Jedna reguła dla walidacji

Wybierz jedną regułę i jej nie naginaj.

Proste podejście:

  • Handlery robią „shape validation” (pola wymagane, podstawowy format).
  • Serwisy robią „meaning validation” (uprawnienia, inwarianty, stan).

Przykład: handler sprawdza, że email jest obecny i wygląda jak adres e-mail. Service sprawdza, że email jest dozwolony i nie jest już używany.

Co przenosi się między warstwami

Zdecyduj wcześnie, czy serwisy zwracają typy domenowe czy DTO.

Czysty domyśl to: handlery używają request/response DTO, serwisy używają typów domenowych, a handler mapuje domenę na odpowiedź. To utrzymuje service stabilny, nawet gdy kontrakt HTTP się zmienia.

Jeśli mapowanie wydaje się uciążliwe, trzymaj się spójnie: niech service zwraca typ domenowy plus typowany błąd, a kształt JSON zostaw w handlerze.

Zdefiniuj standardową odpowiedź błędu i mapę kodów statusu

Jeśli chcesz, by generowane endpointy wyglądały jak napisane przez tę samą osobę, zamknij odpowiedzi błędów wcześnie. Generowanie działa najlepiej, gdy format wyjścia jest niepodważalny: jedna struktura JSON, jedna mapa kodów statusu i jedna zasada, co jest ujawniane.

Zacznij od pojedynczej koperty błędu, której każdy endpoint używa przy porażce. Trzymaj ją małą i przewidywalną:

{
  "code": "validation_failed",
  "message": "One or more fields are invalid.",
  "details": {
    "fields": {
      "email": "must be a valid email address",
      "age": "must be greater than 0"
    }
  },
  "request_id": "req_01HR..."
}

Użyj code dla maszyn (stabilne i przewidywalne) i message dla ludzi (krótki i bezpieczny). Włóż opcjonalne dane strukturalne do details. Dla walidacji prosty mapowany obiekt details.fields jest łatwy do wygenerowania i prosty do wyświetlenia przez klientów obok pól formularza.

Następnie spisz mapę kodów statusu i trzymaj się jej. Im mniej sporów na temat każdego endpointu, tym lepiej. Jeśli chcesz zarówno 400 jak i 422, rozgranicz to explicite:

  • bad_json -> 400 Bad Request (malformed JSON)
  • validation_failed -> 422 Unprocessable Content (well-formed JSON, invalid fields)
  • not_found -> 404 Not Found
  • conflict -> 409 Conflict (duplicate key, version mismatch)
  • unauthorized -> 401 Unauthorized
  • forbidden -> 403 Forbidden
  • internal -> 500 Internal Server Error

Zdecyduj, co logujesz, a co zwracasz. Dobra zasada: klient otrzymuje bezpieczny komunikat i request ID; logi zawierają pełny błąd i kontekst wewnętrzny (SQL, payloady upstream, identyfikatory użytkowników), których nigdy nie chcesz ujawniać.

Na koniec ustandaryzuj request_id. Akceptuj nagłówek z ID, jeśli jest obecny (z API gateway), w przeciwnym razie generuj je na krawędzi (middleware). Dołączaj do kontekstu, umieszczaj w logach i zwracaj w każdej odpowiedzi błędu.

Układ folderów i nazewnictwo, które czynią generowanie przewidywalnym

Jeśli chcesz, żeby scaffolding pozostał spójny, układ folderów musi być nudny i powtarzalny. Generatory podążają za wzorcami, które widzą, ale dryfują, gdy pliki są rozsiane lub nazwy zmieniają się w zależności od funkcji.

Wybierz jedno konwencję nazewniczą i jej się trzymaj. Wybierz jedno słowo dla każdej rzeczy i trzymaj je: handler, service, repo, request, response. Jeśli trasa to POST /users, nazwy plików i typów trzymaj wokół users i create (nie czasem register, czasem addUser).

Prosty układ pasujący do typowych warstw:

internal/
  httpapi/
    handlers/
    users_handler.go
  services/
    users_service.go
  data/
    users_repo.go
  apitypes/
    users_types.go

Zdecyduj, gdzie trzymać typy współdzielone, bo tutaj projekty często się komplikują. Jedna użyteczna zasada:

  • Typy request/response API żyją w internal/apitypes (dopasowane do JSON i wymagań walidacyjnych).
  • Typy domenowe żyją bliżej warstwy service (dopasowane do reguł biznesowych).

Jeśli typ ma tagi JSON i jest projektowany pod klientów, traktuj go jako typ API.

Trzymaj zależności handlera minimalne i zrób tę zasadę explicite:

  • Handlery importują tylko: routing/http, context, apitypes i services
  • Serwisy importują: typy domenowe i dostęp do danych
  • Data access importuje: driver bazy danych i helpery zapytań
  • Żaden handler nie importuje pakietu bazy danych bezpośrednio

Napisz krótki dokument wzorca w repo root (zwykły Markdown wystarczy). Dołącz strukturę folderów, zasady nazewnictwa i jeden mały przykład przepływu (handler -> service -> repo oraz które pliki zawierają każdą część). To jest dokładna referencja, którą wklejasz do generatora, żeby nowe endpointy za każdym razem pasowały do struktury.

Stwórz jeden referencyjny endpoint, który ustala wzorzec

Standardize errors everywhere
Create new endpoints that reuse your error envelope and status-code map.
Generate Endpoint

Zanim wygenerujesz dziesięć endpointów, stwórz jeden endpoint, któremu ufasz. To złoty standard: plik, na który możesz wskazać i powiedzieć: „Nowy kod musi tak wyglądać.” Możesz go napisać od zera albo zrefaktoryzować istniejący, aż będzie pasował.

Trzymaj handler cienki. Jeden ruch, który bardzo pomaga: wstaw interfejs między handlerem a service, żeby handler zależał od kontraktu, a nie od konkretnej struktury.

Dodaj krótkie komentarze w referencyjnym endpoint tylko tam, gdzie przyszły generowany kod może się potknąć. Wyjaśnij decyzje (dlaczego 400 vs 422, dlaczego create zwraca 201, dlaczego ukrywasz błędy wewnętrzne za generycznym komunikatem). Pomiń komentarze, które tylko powtarzają kod.

Gdy referencyjny endpoint działa, wyciągnij helpery tak, by każdy nowy endpoint miał mniej szans na dryf. Najbardziej wielokrotnego użytku helpery to zwykle:

  • Bind JSON i obsługa źle sformatowanych ciał
  • Walidacja inputu i zwracanie błędów po polach
  • Spójne zapisywanie odpowiedzi JSON
  • Mapowanie błędów domenowych na kody HTTP

Oto jak „cienki handler + interfejs” może wyglądać w praktyce:

type UserService interface {
	CreateUser(ctx context.Context, in CreateUserInput) (User, error)
}

func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
	var in CreateUserRequest
	if err := BindJSON(r, &in); err != nil {
		WriteError(w, ErrBadJSON) // 400: malformed JSON
		return
	}
	if err := Validate(in); err != nil {
		WriteError(w, err) // 422: validation details
		return
	}
	user, err := h.svc.CreateUser(r.Context(), in.ToInput())
	if err != nil {
		WriteError(w, err)
		return
	}
	WriteJSON(w, http.StatusCreated, user)
}

Zamknij to paroma testami (nawet mały table test dla mapowania błędów). Generowanie działa najlepiej, gdy ma jeden czysty wzorzec, naśladowany.

Krok po kroku: niech Claude wygeneruje nowy endpoint zgodny z wzorcem

Spójność zaczyna się od tego, co wklejasz i czego zabraniasz. Dla nowego endpointu daj dwie rzeczy:

  1. Twój referencyjny endpoint (idealny przykład)
  2. Krótką notatkę wzorca, która nazywa pakiety, funkcje i helpery, których trzeba użyć

1) Najpierw dostarcz kontekst (reference + reguły)

Dołącz handler, metodę service, typy request/response i wszelkie wspólne helpery, których endpoint używa. Następnie określ kontrakt prostymi słowami:

  • Trasa + metoda (przykład: POST /v1/widgets)
  • Pola JSON żądania (wymagane vs opcjonalne)
  • Kształt JSON odpowiedzi
  • Przypadki błędów i kody statusu
  • Pliki, które spodziewasz się otrzymać (i tylko te pliki)

Bądź eksplicytny co musi się zgadzać: nazwy, ścieżki pakietów i funkcje helperów (WriteJSON, BindJSON, WriteError, twój validator).

2) Poproś o output w dokładnym kształcie, jakiego chcesz

Ścisły prompt zapobiega „pomocnym” refaktom. Na przykład:

Using the reference endpoint below and the pattern notes, generate a new endpoint.
Contract:
- Route: POST /v1/widgets
- Request: {"name": string, "color": string}
- Response: {"id": string, "name": string, "color": string, "createdAt": string}
- Errors: invalid JSON -> 400; validation -> 422; duplicate name -> 409; unexpected -> 500
Output ONLY these files:
1) internal/http/handlers/widgets_create.go
2) internal/service/widgets.go (add method only)
3) internal/types/widgets.go (add types only)
Do not change: router setup, existing error format, existing helpers, or unrelated files.
Must use: package paths and helper functions exactly as in the reference.

Jeśli używasz testów, poproś o nie explicite (i nazwij plik testowy). W przeciwnym razie model może je pominąć lub wymyślić własne ustawienie testowe.

Zrób szybkie sprawdzenie diff po wygenerowaniu. Jeśli zmienił wspólne helpery, rejestrację routera lub standardową odpowiedź błędu, odrzuć output i ostrzej powtórz reguły „do not change”.

Powtarzalny szablon promptu dla spójnego scaffoldu endpointów

Output jest tylko tak spójny, jak wejście. Najszybszy sposób, by uniknąć „prawie dobrego” kodu, to używać tego samego szablonu promptu za każdym razem, z małym snapshotem kontekstu z repo.

Szablon promptu

Skopiuj, wklej i wypełnij pola:

You are editing an existing Go HTTP API.

CONTEXT
- Folder tree (only the relevant parts):
  <paste a small tree: internal/http, internal/service, internal/repo, etc>
- Key types and patterns:
  - Handler signature style: <example>
  - Service interface style: <example>
  - Request/response DTOs live in: <package>
- Standard error response JSON:
  {
    "error": {
      "code": "invalid_argument",
      "message": "...",
      "details": {"field": "reason"}
    }
  }
- Status code map:
  invalid_json -> 400
  invalid_argument -> 422
  not_found -> 404
  conflict -> 409
  internal -> 500

TASK
Add a new endpoint: <METHOD> <PATH>
- Handler name: <Name>
- Service method: <Name>
- Request JSON example:
  {"name":"Acme"}
- Success response JSON example:
  {"id":"123","name":"Acme"}

CONSTRAINTS
- No new dependencies.
- Keep functions small and single-purpose.
- Match existing naming, folder layout, and error style exactly.
- Do not refactor unrelated files.

ACCEPTANCE CHECKS
- Code builds.
- Existing tests pass (add tests only if the repo already uses them for handlers/services).
- Run gofmt on changed files.

FINAL INSTRUCTION
Before writing code, list any assumptions you must make. If an assumption is risky, ask a short question instead.

To działa, ponieważ wymusza trzy rzeczy: blok kontekstu (co istnieje), blok ograniczeń (czego nie robić) i konkretne przykłady JSON (żeby kształty się nie rozjechały). Ostatnia instrukcja to zabezpieczenie: jeśli model nie jest pewien, powinien zapytać zanim wygeneruje kod.

Realistyczny przykład: dodanie endpointu Create bez złamania stylu

Scaffold Go endpoints fast
Scaffold a handler-service-repo endpoint from a chat prompt and keep your patterns consistent.
Try Free

Powiedzmy, że chcesz dodać endpoint „Create project”. Cel jest prosty: przyjąć nazwę, wymusić kilka reguł, zapisać i zwrócić nowe ID. Trudność polega na utrzymaniu podziału handler-service-repo i tego samego JSON błędu, którego już używasz.

Spójny przepływ wygląda tak:

  • Handler: bind JSON, wykonaj podstawową walidację pól, wywołaj service
  • Service: zastosuj reguły biznesowe (np. unikalność), wywołaj repo, zwróć wynik domenowy
  • Repo: zapisz w Postgres, zwróć wygenerowane ID

Oto żądanie, które handler akceptuje:

{ "name": "Roadmap", "owner_id": "u_123" }

Po sukcesie zwróć 201 Created. ID powinno pochodzić z jednego miejsca za każdym razem. Na przykład pozwól Postgresowi je wygenerować, a repo niech je zwraca:

{ "id": "p_456", "name": "Roadmap", "owner_id": "u_123", "created_at": "2026-01-09T12:34:56Z" }

Dwie realistyczne ścieżki porażki:

Jeśli walidacja zawiedzie (brak lub za krótka nazwa), zwróć błąd na poziomie pola używając standardowego kształtu i wybranego kodu statusu:

{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid request", "details": { "name": "must be at least 3 characters" } } }

Jeśli nazwa musi być unikalna na właściciela i service znajdzie istniejący projekt, zwróć 409 Conflict:

{ "error": { "code": "PROJECT_NAME_TAKEN", "message": "Project name already exists", "details": { "name": "Roadmap" } } }

Jedna decyzja, która utrzymuje wzorzec czysty: handler sprawdza „czy to żądanie ma właściwy kształt?”, a service odpowiada za „czy to jest dozwolone?”. To rozdzielenie sprawia, że generowane endpointy są przewidywalne.

Najczęstsze błędy, które łamią spójność (i jak ich unikać)

Najszybszy sposób na utratę spójności to pozwolić generatorowi improwizować.

Jednym z częstych dryfów jest nowy kształt błędu. Jeden endpoint zwraca {error: "..."}, inny {message: "..."}, a trzeci dodaje zagnieżdżony obiekt. Napraw to, trzymając jedną kopertę błędu i jedną mapę kodów w jednym miejscu, a następnie wymagaj, by nowe endpointy je ponownie wykorzystywały przez import ścieżki i nazwę funkcji. Jeśli generator proponuje nowe pole, traktuj to jako zmianę API, nie jako wygodę.

Inny dryf to rozrastanie handlera. Zaczyna się niewinnie: waliduj, potem sprawdź uprawnienia, potem zapytaj DB, potem rozgałęzienia reguł biznesowych. Wkrótce każdy handler wygląda inaczej. Trzymaj jedną regułę: handlery tłumaczą HTTP na typowane inputy i outputy; serwisy posiadają decyzje; dostęp do danych zajmuje się zapytaniami.

Niezgodności nazw również się sumują. Jeśli jeden endpoint używa CreateUserRequest, a inny NewUserPayload, stracisz czas na dopasowywanie typów i pisanie glue. Wybierz schemat nazewnictwa i odrzucaj nowe nazwy, chyba że jest ku temu silny powód.

Nigdy nie zwracaj surowych błędów bazy danych klientom. Poza wyciekiem szczegółów, tworzy to niespójne komunikaty i kody statusu. Owijaj błędy wewnętrzne, loguj przyczynę i zwracaj stabilny publiczny kod błędu.

Unikaj dodawania nowych bibliotek „dla wygody”. Każdy dodatkowy validator, helper routera czy pakiet błędów staje się kolejnym stylem do dopasowania.

Zabezpieczenia, które zapobiegają większości uszkodzeń:

  • Wymagaj, by nowe endpointy używały istniejących typów błędów i helperów.
  • Trzymaj handlery wolne od reguł biznesowych i dostępu do DB.
  • Wymuszaj jedną konwencję nazewnictwa dla request/response structów.
  • Mapuj błędy wewnętrzne na publiczne kody, nigdy surowe błędy.
  • Dodawaj zależności tylko z jasnym, pisemnym powodem.

Jeśli nie możesz porównać dwóch endpointów i zobaczyć tego samego kształtu (importy, flow, obsługa błędów), zaostrz prompt i wygeneruj ponownie przed mergem.

Szybka lista kontrolna przed zmergowaniem wygenerowanego endpointu

Ship and test faster
Host your API after scaffolding so you can test real client behavior early.
Deploy App

Zanim zmerge'ujesz cokolwiek wygenerowanego, najpierw sprawdź strukturę. Jeśli kształt jest poprawny, błędy logiczne łatwiej znaleźć.

Kontrole struktury:

  • Flow handlera jest spójny: bind input, validate, call service, map domain errors to HTTP, write response.
  • Kod service zawiera tylko reguły biznesowe: brak bezpośredniego HTTP lub JSON.
  • Odpowiedzi sukcesu pasują do stylu projektu (albo wspólna koperta wszędzie, albo bezpośredni JSON wszędzie).
  • Odpowiedzi błędów są jednolite: te same pola JSON, te same kody, to samo zachowanie request_id.
  • Nazwy i umiejscowienie są nudne: nazwy plików, funkcji i tras pasują do istniejących endpointów i wszystkie pliki są sformatowane gofmt.

Kontrole zachowania:

  • Uruchom testy i dodaj przynajmniej jeden mały test dla nowej gałęzi handler/service.
  • Potwierdź, że błędy walidacji zwracają ten sam kod i status co podobne endpointy.
  • Wywołaj jeden znany błąd service (np. "not found" lub "conflict") i potwierdź kod HTTP i kształt JSON.
  • Przeskanuj pod kątem pozostałości copy-paste: zła ścieżka trasy, błędny komunikat w logu, niezgodne nazwy DTO.
  • Zbuduj i uruchom serwer lokalnie raz, żeby upewnić się, że wiring i importy są poprawne.

Następne kroki: ustandaryzuj wzorzec, potem skaluj bezpiecznie

Traktuj wzorzec jako wspólny kontrakt, nie preferencję. Trzymaj dokument „jak budujemy endpointy” blisko kodu i utrzymuj jeden referencyjny endpoint pokazujący pełne podejście end-to-end.

Skaluj generowanie małymi partiami. Generuj 2–3 endpointy, które trafiają różne przypadki (proste read, create z walidacją, update z not-found). Potem zatrzymaj się i dopracuj. Jeśli przeglądy ciągle znajdują ten sam dryf stylu, zaktualizuj dokument bazowy i referencyjny endpoint zanim wygenerujesz więcej.

Pętla do powtarzania:

  • Spisz bazę: nazwy plików, nazwy funkcji, struktury request/response, kody błędów i gdzie odbywa się walidacja.
  • Miej jeden endpoint „golden” i aktualizuj go pierwszy, gdy wzorzec się zmienia.
  • Generuj partiami kilka endpointów, sprawdź spójność, potem dostosuj prompt i dokument wzorca.
  • Refaktoryzuj starsze endpointy partiami i miej ścieżkę rollback, jeśli zachowanie się zmieni.
  • Śledź jedną metrykę przez tydzień: czas dodania endpointu, wskaźnik błędów po mergu lub czas przeglądu.

Jeśli chcesz ciaśniejszego cyklu build-review, platforma vibe-coding jak Koder.ai (koder.ai) może pomóc Ci szkielować i iterować szybko w chatowym workflow, a potem eksportować źródło, gdy pasuje do twojego standardu. Narzędzie ma mniejsze znaczenie niż reguła: twoja baza stoi na straży.

Często zadawane pytania

What’s the fastest way to stop a Go API from getting inconsistent?

Zamroź powtarzalny szablon na wczesnym etapie: spójny podział warstw (handler → service → data access), jedna koperta błędu i mapa statusów HTTP. Następnie użyj jednego „reference endpoint”, którego każde nowe endpoint musi się trzymać.

What should a handler do (and not do)?

Trzymaj handlery tylko dla HTTP:

  • Bind/parsuj żądanie
  • Wykonaj prostą „shape validation” (pola wymagane, podstawowe formaty)
  • Wywołaj service
  • Mapuj typowane błędy na kody HTTP
  • Zapisz JSON przy użyciu wspólnych helperów

Jeśli widzisz SQL, sprawdzanie uprawnień lub rozgałęzienia biznesowe w handlerze, przenieś to do service.

What belongs in the service layer?

Umieść logikę biznesową i decyzje w service:

  • Uprawnienia i reguły dostępu
  • Inwarianty (przejścia stanów, reguły unikalności, „allowed” checks)
  • Orkiestracja między repozytoriami i wywołaniami zewnętrznymi

Service powinien zwracać rezultaty domenowe i typowane błędy — bez kodów HTTP i bez formowania JSON.

What belongs in the data access/repository layer?

Zachowaj kwestie trwałości danych w izolacji:

  • SQL/zapytania i transakcje
  • Mapowanie wierszy na struktury
  • Zwracanie błędów magazynu (które service może zinterpretować)

Unikaj kodowania formatów odpowiedzi API lub wymuszania reguł biznesowych w repo, poza podstawową integralnością danych.

Where should validation live?

Proste domyślne rozłożenie:

  • Handlery walidują kształt żądania (brakujące pola, podstawowy format)
  • Serwisy walidują znaczenie (uprawnienia, inwarianty, stan)

Przykład: handler sprawdza, że email istnieje i wygląda jak email; service sprawdza, czy jest dozwolony i nie jest już używany.

What should a standard API error response look like?

Używaj jednej, standardowej koperty błędu wszędzie i trzymaj ją stabilną. Praktyczny kształt:

  • code dla maszyn (stabilne)
  • message dla ludzi (krótki i bezpieczny)
  • details dla danych strukturalnych (np. błędy pól)
  • request_id dla śledzenia

To zapobiega special-case'om po stronie klienta i ułatwia przewidywalność generowanych endpointów.

How do I choose between 400 vs 422 vs 409 for errors?

Spisz mapę statusów i trzymaj się jej za każdym razem. Typowy podział:

  • 400 dla źle sformatowanego JSON (bad_json)
  • 422 dla błędów walidacji (validation_failed)
  • 404 dla nie znaleziono (not_found)
Should I ever return raw database errors to clients?

Zwracaj bezpieczne, spójne błędy publiczne i loguj prawdziwą przyczynę wewnętrznie.

  • Odpowiedź: stabilny code, krótki message, plus request_id
  • Logi: pełne szczegóły błędu (SQL, payloady upstream, identyfikatory użytkowników)

To zapobiega wyciekom szczegółów i różnicom w komunikatach między endpointami.

What is a reference endpoint, and why do I need one?

Stwórz jeden „golden” endpoint, któremu ufasz i wymagaj, by nowe endpointy się do niego upodabniały:

  • Ten sam przepływ (bind → validate → service → mapowanie błędów → JSON)
  • Te same helpery (BindJSON, WriteJSON, WriteError, itd.)
  • Ta sama struktura folderów i nazewnictwo

Dodaj kilka małych testów (np. table tests dla mapowania błędów) żeby utrwalić wzorzec.

How do I prompt Claude to generate new endpoints without breaking my structure?

Daj modelowi ścisły kontekst i ograniczenia:

  • Wklej reference endpoint i zasady wzorca
  • Określ trasę, przykłady JSON request/response i przypadki błędów
  • Wymień dokładnie które pliki może zmodyfikować
  • Wyraźnie powiedz, czego nie wolno zmieniać (router, format błędu, helpery)

Po generacji odrzuć diffs, które „ulepszają” architekturę zamiast trzymać się baseline.

Spis treści
Dlaczego API w Go robią się nieporządne, jeśli wzorce nie są ustalone wcześnieWybierz jeden podział warstw: handler, service i dostęp do danychZdefiniuj standardową odpowiedź błędu i mapę kodów statusuUkład folderów i nazewnictwo, które czynią generowanie przewidywalnymStwórz jeden referencyjny endpoint, który ustala wzorzecKrok po kroku: niech Claude wygeneruje nowy endpoint zgodny z wzorcemPowtarzalny szablon promptu dla spójnego scaffoldu endpointówRealistyczny przykład: dodanie endpointu Create bez złamania styluNajczęstsze błędy, które łamią spójność (i jak ich unikać)Szybka lista kontrolna przed zmergowaniem wygenerowanego endpointuNastępne kroki: ustandaryzuj wzorzec, potem skaluj bezpiecznieCzęsto zadawane pytania
Udostępnij
Koder.ai
Build your own app with Koder today!

The best way to understand the power of Koder is to see it for yourself.

Start FreeBook a Demo
  • 409 dla konfliktów (duplikat/wersjonowanie)
  • 500 dla nieoczekiwanych błędów
  • Klucz to spójność: bez debaty dla każdego endpointu.