7 min

Projektowanie publicznego API dla początkujących twórców SaaS: podstawy

Praktyczne projektowanie publicznego API dla początkujących twórców SaaS: wybierz wersjonowanie, paginację, limity, dokumentację i małe SDK, które możesz szybko wypuścić.

Projektowanie publicznego API dla początkujących twórców SaaS: podstawy

Prawdziwy problem: wysłać API, które potrafisz utrzymać

Publiczne API to nie tylko endpoint, który wystawiasz. To obietnica wobec osób spoza twojego zespołu, że kontrakt będzie działać, nawet gdy zmieniasz produkt.

Trudne nie jest napisanie v1. Trudne jest utrzymanie jego stabilności, gdy poprawiasz błędy, dodajesz funkcje i dowiadujesz się, czego naprawdę potrzebują klienci.

Wczesne decyzje pojawiają się później jako zgłoszenia do wsparcia. Jeśli odpowiedzi zmieniają kształt bez ostrzeżenia, jeśli nazwy są niespójne, albo klienci nie potrafią stwierdzić, czy zapytanie się powiodło, wprowadzasz tarcie. To tarcie zamienia się w brak zaufania, a brak zaufania sprawia, że ludzie przestają budować na twoim produkcie.

Szybkość też ma znaczenie. Większość początkujących twórców SaaS musi wysłać coś użytecznego szybko, a potem to poprawiać. Kompromis jest prosty: im szybciej wypuścisz bez zasad, tym więcej czasu spędzisz cofając te decyzje, gdy przyjdą prawdziwi użytkownicy.

Wystarczające dla v1 zwykle oznacza mały zestaw endpointów odpowiadających rzeczywistym akcjom użytkowników, spójną nazwę i kształt odpowiedzi, jasną strategię zmian (nawet jeśli to tylko v1), przewidywalną paginację i rozsądne limity oraz dokumentację pokazującą dokładnie, co wysłać i co się otrzyma z powrotem.

Konkretny przykład: wyobraź sobie klienta, który buduje integrację tworzącą faktury co noc. Jeśli później zmienisz nazwę pola, format daty lub zaczniesz zwracać częściowe wyniki bez ostrzeżenia, ich zadanie zawiedzie o 2:00 rano. Oni obwiniają twoje API, nie swój kod.

Jeśli budujesz z narzędziem prowadzonym przez czat, takim jak Koder.ai, łatwo jest szybko wygenerować wiele endpointów. To w porządku, ale trzymaj publiczną powierzchnię małą. Możesz trzymać endpointy wewnętrzne prywatnie, dopóki nie nauczysz się, co powinno być częścią długoterminowego kontraktu.

Zacznij od małej, jasnej powierzchni API

Dobre projektowanie publicznego API zaczyna się od wyboru małego zestawu rzeczowników (zasobów), które odpowiadają temu, jak klienci mówią o twoim produkcie. Trzymaj nazwy zasobów stabilne, nawet jeśli twoja wewnętrzna baza danych się zmienia. Kiedy dodajesz funkcje, wol preferować dodawanie pól lub nowych endpointów zamiast zmiany nazw rdzeniowych zasobów.

Praktyczny zestaw startowy dla wielu produktów SaaS to: users, organizations, projects i events. Jeśli nie potrafisz wyjaśnić zasobu jednym zdaniem, prawdopodobnie nie jest gotowy, by być publicznym.

Użycie HTTP utrzymuj nudnym i przewidywalnym:

  • GET odczytuje dane (bez efektów ubocznych)
  • POST tworzy coś (lub uruchamia akcję)
  • PATCH aktualizuje kilka pól
  • DELETE usuwa lub wyłącza coś

Auth nie musi być wyszukane pierwszego dnia. Jeśli twoje API to głównie server-to-server (klienci wywołują z backendu), klucze API często wystarczą. Jeśli klienci muszą działać jako indywidualni użytkownicy końcowi, lub spodziewasz się integracji third-party, gdzie użytkownicy nadają dostęp, OAuth zwykle lepiej pasuje. Zapisz decyzję prostym językiem: kto jest dzwoniącym i do czyich danych ma dostęp?

Ustal oczekiwania wcześnie. Bądź wyraźny, co jest wspierane, a co jest tylko best-effort. Na przykład: list endpoints są stabilne i kompatybilne wstecz, ale filtry wyszukiwania mogą się rozszerzać i nie są gwarantowane jako wyczerpujące. To zmniejsza liczbę zgłoszeń i daje ci swobodę do ulepszania.

Jeśli budujesz na platformie vibe-coding jak Koder.ai, traktuj API jak produktowy kontrakt: najpierw trzymaj kontrakt mały, potem rozwijaj go w oparciu o rzeczywiste użycie, nie przypuszczenia.

Wersjonowanie bez wpychania się w róg

Wersjonowanie dotyczy głównie oczekiwań. Klient chce wiedzieć: czy moja integracja padnie w przyszłym tygodniu? Ty chcesz mieć przestrzeń do poprawiania rzeczy bez strachu.

Wersjonowanie w URL vs w nagłówkach

Wersjonowanie oparte na nagłówkach może wyglądać schludnie, ale łatwo je ukryć przed logami, cache'ami i zrzutami ekranu do wsparcia. Wersjonowanie w URL jest zwykle najprostszym wyborem: /v1/.... Gdy klient wyśle niepoprawne zapytanie, od razu widać wersję. Ułatwia też uruchamianie v1 i v2 obok siebie.

Czym naprawdę jest zmiana łamiąca?

Zmiana jest łamiąca, jeśli poprawnie zachowujący się klient może przestać działać bez zmiany swojego kodu. Typowe przykłady:

  • Zmiana nazwy pola (np. customer_id na customerId)
  • Zmiana typu pola (string na number) lub jego znaczenia
  • Usunięcie endpointu lub pola w odpowiedzi, na które klienci mogą polegać
  • Zaostrzenie reguł walidacji (wcześniej opcjonalne, teraz wymagane)
  • Zmiana wymagań dotyczących autoryzacji lub domyślnych uprawnień

Bezpieczna zmiana to taka, którą stare klienci mogą zignorować. Dodanie nowego opcjonalnego pola zwykle jest bezpieczne. Na przykład dodanie plan_name do odpowiedzi GET /v1/subscriptions nie zepsuje klientów, którzy czytają tylko status.

Praktyczna zasada: nie usuwaj ani nie przekształcaj pól w tej samej wersji major. Dodawaj nowe pola, zachowuj stare i wycofuj je dopiero, gdy jesteś gotowy zdeprecjonować całą wersję.

Polityka deprecjacji, której możesz przestrzegać

Utrzymaj prostotę: ogłaszaj deprecjacje wcześnie, zwracaj jasne ostrzeżenie w odpowiedziach i ustaw datę końcową. Dla pierwszego API okno 90 dni jest często realistyczne. W tym czasie trzymaj v1 działające, opublikuj krótką notę migracyjną i upewnij się, że wsparcie potrafi wskazać jedno zdanie: v1 działa do tej daty; oto co się zmieniło w v2.

Jeśli budujesz na platformie takiej jak Koder.ai, traktuj wersje API jak snapshoty: wysyłaj ulepszenia w nowej wersji, trzymaj starą stabilną i odetnij ją dopiero po tym, jak dasz klientom czas na migrację.

Wzorce paginacji, które pozostają przewidywalne

Paginacja to miejsce, gdzie zdobywa się lub traci zaufanie. Jeśli wyniki skaczą między zapytaniami, ludzie przestają ufać twojemu API.

Użyj page/limit, gdy zbiór danych jest mały, zapytanie proste, a użytkownicy często chcą strony 3 z 20. Użyj paginacji kursora, gdy listy mogą rosnąć, nowe elementy pojawiają się często lub użytkownik dużo sortuje i filtruje. Paginacja kursora utrzymuje stabilność sekwencji nawet, gdy pojawiają się nowe rekordy.

Kilka zasad, które utrzymają paginację wiarygodną:

  • Zawsze zdefiniuj domyślne sortowanie (np. created_at desc).
  • Dodaj tie-breaker (np. id), by porządek był deterministyczny.
  • Traktuj paginację jako część kontraktu: zmiana sortowania później to zmiana łamiąca.
  • Zwracaj minimum potrzebne do kontynuacji: items plus next cursor (lub next page).

Totale są trudne. total_count może być kosztowny na dużych tabelach, szczególnie z filtrami. Jeśli możesz go dostarczyć tanio, dodaj go. Jeśli nie możesz, pomiń go lub udostępnij opcjonalnie przez flagę zapytania.

Here are simple request/response shapes.

// Page/limit
GET /v1/invoices?page=2\u0026limit=25\u0026sort=created_at_desc

{
  \"items\": [{\"id\":\"inv_1\"},{\"id\":\"inv_2\"}],
  \"page\": 2,
  \"limit\": 25,
  \"total_count\": 142
}

// Cursor-based
GET /v1/invoices?limit=25\u0026cursor=eyJjcmVhdGVkX2F0IjoiMjAyNi0wMS0wOVQxMDozMDowMFoiLCJpZCI6Imludl8xMDAifQ==

{
  \"items\": [{\"id\":\"inv_101\"},{\"id\":\"inv_102\"}],
  \"next_cursor\": \"eyJjcmVhdGVkX2F0IjoiMjAyNi0wMS0wOVQxMDoyNTowMFoiLCJpZCI6Imludl8xMjUifQ==\"
}

Limity szybkości i przyjazne ponawianie

Plan Your v1 API First
Use Koder.ai Planning Mode to map resources, endpoints, and examples before generating code.

Rate limits to mniej kwestia surowości, a bardziej kwestia bycia online. Chronią twoją aplikację przed nagłymi skokami ruchu, twoją bazę danych przed drogimi zapytaniami wykonywanymi zbyt często i twój portfel przed niespodziewanymi rachunkami za infrastrukturę. Limit to też kontrakt: klienci wiedzą, jak wygląda normalne użycie.

Zacznij prosto i dostosuj później. Wybierz coś, co obejmuje typowe użycie z zapasem na krótkie gwałtowne skoki, potem obserwuj ruch. Jeśli nie masz jeszcze danych, bezpieczny domyślny wybór to limit na klucz API np. 60 zapytań na minutę plus mały allowance na burst. Jeśli jeden endpoint jest dużo cięższy (np. search lub exports), nadaj mu ostrzejszy limit lub osobne koszty zamiast karać każde zapytanie.

Kiedy egzekwujesz limity, ułatw klientom poprawne zachowanie. Zwróć 429 Too Many Requests i dołącz kilka standardowych nagłówków:

  • X-RateLimit-Limit: maksymalna dozwolona liczba w oknie
  • X-RateLimit-Remaining: ile zostało
  • X-RateLimit-Reset: kiedy okno się resetuje (timestamp lub sekundy)
  • Retry-After: jak długo czekać przed ponowną próbą

Klienci powinni traktować 429 jako normalny stan, nie błąd do obalania. Uprzejmy wzorzec ponawiania utrzymuje obie strony zadowolone:

  • Poczekaj na Retry-After, gdy jest obecny
  • W przeciwnym razie użyj wykładniczego backoffu (np. 1s, 2s, 4s)
  • Dodaj odrobinę losowości (jitter), aby wielu klientów nie próbowało w tym samym czasie
  • Ogranicz maksymalny czas oczekiwania (np. 30–60s)

Przykład: jeśli klient uruchamia synchronizację nocną, która mocno obciąża API, jego zadanie może rozłożyć zapytania na minutę i automatycznie zwalniać przy 429 zamiast kończyć całe zadanie niepowodzeniem.

Błędy, kody statusu i bezpieczne zapisy

Jeśli twoje błędy API są trudne do odczytania, liczba zgłoszeń do wsparcia szybko rośnie. Wybierz jeden kształt błędu i stosuj go wszędzie, także przy 500. Prosty standard to: code, message, details oraz request_id, który użytkownik może wkleić na czacie wsparcia.

Here is a small, predictable format.

{
  \"error\": {
    \"code\": \"validation_error\",
    \"message\": \"Some fields are invalid.\",
    \"details\": {
      \"fields\": [
        {\"name\": \"email\", \"issue\": \"must be a valid email\"},
        {\"name\": \"plan\", \"issue\": \"must be one of: free, pro, business\"}
      ]
    },
    \"request_id\": \"req_01HT...\"
  }
}

Używaj kodów HTTP w ten sam sposób zawsze: 400 dla złego inputu, 401 gdy auth brak lub nieprawidłowy, 403 gdy użytkownik jest uwierzytelniony, ale nie ma uprawnień, 404 gdy zasób nie istnieje, 409 dla konfliktów (np. duplikat unikalnej wartości lub zły stan), 429 dla limitów, i 500 dla błędów serwera. Spójność bije spryt.

Ułatw naprawianie błędów walidacji. Wskazówki na poziomie pola powinny odwoływać się do dokładnej nazwy parametru użytej w dokumentacji, nie do wewnętrznej kolumny bazy danych. Jeśli istnieje wymóg formatu (data, waluta, enum), powiedz, co akceptujesz i pokaż przykład.

Retry to miejsce, gdzie wiele API przypadkowo tworzy duplikaty. Dla ważnych akcji POST (płatności, tworzenie faktury, wysyłanie emaili) wspieraj idempotency keys, żeby klienci mogli bezpiecznie ponawiać żądania.

  • Akceptuj nagłówek Idempotency-Key na wybranych endpointach POST.
  • Przechowuj klucz z wynikiem przez krótki okres (np. 24 godziny).
  • Przy powtórnym kluczu zwróć tę samą odpowiedź co przy pierwszym żądaniu.
  • Jeśli pierwsze żądanie nadal się wykonuje, zwróć jasną odpowiedź „spróbuj ponownie”, zamiast tworzyć drugi zasób.

Ten jeden nagłówek zapobiega wielu bolesnym edge case'om, gdy sieć szwankuje lub klienci mają timeouty.

Przykładowy scenariusz: małe SaaS billing API w praktyce

Wyobraź sobie prosty SaaS z trzema głównymi obiektami: projects, users i invoices. Projekt ma wielu użytkowników, a każdy projekt dostaje miesięczne faktury. Klienci chcą zsynchronizować faktury do narzędzia księgowego i pokazać podstawowe informacje billingowe we własnej aplikacji.

Czyste v1 może wyglądać tak:

GET  /v1/projects/{project_id}
GET  /v1/projects/{project_id}/invoices
POST /v1/projects/{project_id}/invoices

Teraz pojawia się zmiana łamiąca. W v1 przechowujesz kwoty faktur jako integer w centach: amount_cents: 1299. Później potrzebujesz multi-walut i wartości dziesiętnych, więc chcesz amount: "12.99" i currency: "USD". Jeśli nadpiszesz stare pole, każda istniejąca integracja się zepsuje. Wersjonowanie unika paniki: trzymaj v1 stabilne, wypuść /v2/... z nowymi polami i wspieraj oba dopóki klienci nie zmigrują.

Dla listowania faktur użyj przewidywalnego kształtu paginacji. Na przykład:

GET /v1/projects/p_123/invoices?limit=50\u0026cursor=eyJpZCI6Imludl85OTkifQ==

200 OK
{
  \"data\": [ {\"id\":\"inv_1001\"}, {\"id\":\"inv_1000\"} ],
  \"next_cursor\": \"eyJpZCI6Imludl8xMDAwIn0=\"
}

Pewnego dnia klient importuje faktury w pętli i trafia na twój limit. Zamiast losowych błędów otrzymuje jasną odpowiedź:

  • 429 Too Many Requests
  • Retry-After: 20
  • małe body błędu typu { \"error\": { \"code\": \"rate_limited\" } }

Po stronie klienta można wstrzymać na 20 sekund, a potem kontynuować od tego samego cursor bez ponownego pobierania wszystkiego lub tworzenia duplikatów faktur.

Krok po kroku: prosty plan wydania v1 API

Ship Changes With Rollback
Use snapshots and rollback to ship API improvements without breaking your stable contract.

Wypuszczenie v1 idzie lepiej, gdy traktujesz to jak małe wydanie produktu, nie jak stertę endpointów. Cel jest prosty: ludzie mogą na nim budować, a ty możesz go ulepszać bez niespodzianek.

Praktyczny plan na 1 tydzień (nawet dla malutkiego zespołu)

Zacznij od napisania jednej strony wyjaśniającej, do czego służy twoje API, a do czego nie. Utrzymaj powierzchnię na tyle małą, by móc wytłumaczyć ją na głos w minutę.

Użyj tej sekwencji i nie przechodź dalej, dopóki każdy krok nie będzie wystarczająco dobry:

  1. Szkic jednostronicowej specyfikacji, która nazywa twoje główne zasoby i pierwszą garstkę endpointów, które będziesz wspierać (pomyśl 5–10). Dołącz wzorzec base URL, metodę auth i wymagane nagłówki.
  2. Dla każdego endpointu napisz jedno realistyczne żądanie i jedną realistyczną odpowiedź. Użyj rzeczywistych nazw pól, które planujesz wprowadzić. Te przykłady stają się twoją pierwszą dokumentacją i pierwszymi testami.
  3. Dodaj krótki dział zasad: jak wyglądają błędy, jak działa paginacja (jeśli istnieje endpoint listy), jakie są rate limits i które pola są stabilne vs mogą się zmieniać.
  4. Zrób wewnętrzny test z fałszywym klientem. Udawaj, że jesteś klientem budującym integrację w nowym repo. Zmierz czas do pierwszego udanego wywołania i zanotuj, gdzie się zdezorientowałeś.
  5. Opublikuj kontrakt v1: co jest bezpieczne (pola addytywne), co wymaga nowej wersji i ile czasu dasz na zmiany.

Jeśli budujesz z workflow generującym kod (np. używając Koder.ai do szkicowania endpointów i odpowiedzi), i tak zrób test „fake-client”. Wygenerowany kod może wyglądać poprawnie, a wciąż być nieintuicyjny w użyciu.

Profit to mniej maili do wsparcia, mniej hotfixów i v1, który naprawdę potrafisz utrzymać.

Wysyłanie małego SDK bez over-engineeringu

Pierwsze SDK to nie drugi produkt. Traktuj je jako cienką, przyjazną nakładkę na twoje HTTP API. Powinno upraszczać najczęstsze wywołania, ale nie ukrywać działania API. Jeśli ktoś potrzebuje funkcji, której nie zapakowałeś, powinien dalej móc zrobić surowe żądanie HTTP.

Wybierz jeden język na start, bazując na tym, czego faktycznie używają twoi klienci. Dla wielu B2B SaaS to często JavaScript/TypeScript lub Python. Wypuszczenie jednego solidnego SDK jest lepsze niż trzech niedokończonych.

Co powinno zawierać małe SDK

Dobry zestaw startowy to:

  • Obsługa auth (API key lub OAuth token) w jednym miejscu
  • Sensowne timeouty i automatyczne retry dla bezpiecznych requestów (GET), z backoffem
  • Pomocniki paginacji, które zwracają iterator lub funkcję next page
  • Jasne modele request/response (nawet podstawowe typy)
  • Escape hatch dla custom headers i surowych wywołań HTTP

Możesz napisać to ręcznie lub wygenerować z OpenAPI. Generacja jest świetna, gdy spec jest dokładna i chcesz typowania, ale często produkuje dużo kodu. Na początku ręcznie napisany minimalny klient plus plik OpenAPI dla dokumentacji zwykle wystarczy. Możesz potem przejść na generowane klienty bez łamania użytkowników, jeśli publiczny interfejs SDK pozostanie stabilny.

Wersjonuj SDK oddzielnie od API

Wersja API powinna podążać za regułami kompatybilności. Wersja SDK powinna podążać za zasadami pakietowania.

Jeśli dodasz nowe opcjonalne parametry lub endpointy, to zwykle drobna zmiana SDK. Zarezerwuj duże wydania SDK na łamiące zmiany w samym SDK (zmienione nazwy metod, zmienione domyślne zachowania), nawet jeśli API pozostało niezmienione. To rozdzielenie utrzymuje aktualizacje spokojnymi i redukuje zgłoszenia do supportu.

Typowe błędy generujące wątpliwości wsparcia

Prevent Duplicate Writes
Implement Idempotency-Key handling with generated server code you can edit and own.

Większość zgłoszeń do API nie wynika z bugów. Wynikają ze zaskoczeń. Projektowanie publicznego API to głównie bycie nudnym i przewidywalnym, żeby kod klienta działał miesiąc w miesiąc.

Najszybszy sposób na utratę zaufania to zmiana odpowiedzi bez poinformowania kogokolwiek. Jeśli zmienisz nazwę pola, typ albo zaczniesz zwracać null tam, gdzie wcześniej był wartość, złamiesz klientów w trudno diagnozowalny sposób. Jeśli musisz zmienić zachowanie, wersjonuj to albo dodaj nowe pole i trzymaj stare przez jakiś czas z jasnym planem wycofania.

Paginacja to kolejny powtarzający się problem. Problemy pojawiają się, gdy jeden endpoint używa page/pageSize, inny offset/limit, a trzeci cursors — każdy z innymi domyślnymi wartościami. Wybierz jeden wzorzec na v1 i trzymaj się go wszędzie. Utrzymaj też stabilne sortowanie, żeby następna strona nie pomijała ani nie duplikowała elementów, gdy pojawiają się nowe rekordy.

Błędy powodują dużo wymiany informacji, gdy są niespójne. Częsty scenariusz awarii to jedna usługa zwracająca { "error": "..." }, a inna { "message": "..." } z różnymi kodami HTTP dla tego samego problemu. Klienci wtedy budują brudne, specyficzne dla endpointu handlery.

Oto pięć błędów, które generują najdłuższe wątki mailowe:

  • Ciche zmiany pól (nazwy, typy, znaczenie) bez bumpa wersji lub okna deprecjacji
  • Zasady paginacji różniące się między endpointami lub zmieniające domyślne wartości w czasie
  • Różne formaty błędów, kody statusu lub komunikaty walidacji w różnych endpointach
  • Brak request ID, więc żadna ze stron szybko nie znajdzie konkretnego nieudanego wywołania w logach
  • Limity rate, które uruchamiają się nagle, bez nagłówków, bez jasnej informacji kiedy retry i bez przykładów backoffu

Prosta praktyka pomaga: każda odpowiedź powinna zawierać request_id, a każde 429 powinno wyjaśniać, kiedy spróbować ponownie.

Szybka lista kontrolna i następne kroki

Zanim coś opublikujesz, zrób końcowy przegląd skupiony na spójności. Większość zgłoszeń wynika z drobnych różnic między endpointami, dokumentacją i przykładami.

Szybkie kontrole, które łapią najwięcej problemów:

  • Nazewnictwo: spójne rzeczowniki, pluralizacja zasobów i styl wielkości liter pól (wybierz jeden i trzymaj się go).
  • Przykłady: każdy endpoint ma jeden realistyczny request i response, w tym paginację.
  • Błędy: jasny kształt błędu, stabilne kody błędów i pomocne komunikaty dla częstych niepowodzeń.
  • Limity: zachowanie rate limits jest udokumentowane i odpowiedzi zawierają oczekiwane nagłówki.
  • Bezpieczeństwo: idempotencja dla retry przy tworzeniu i przewidywalne zachowanie przy timeoutach.

Po uruchomieniu obserwuj, czego ludzie faktycznie używają, a nie tego, czego się spodziewałeś. Mały dashboard i cotygodniowy przegląd wystarczą na początku.

Monitoruj te sygnały najpierw:

  • Skoki 429 (kto jest limitowany i dlaczego).
  • p95 latency per endpoint (wolne endpointy często kryją N+1 queries).
  • Top endpoints i parametry (twoja rzeczywista powierzchnia API).
  • Współczynnik błędów wg kodu statusu (400 vs 401 vs 500).
  • Timeouty i retry (klienci mogą pętlować bez zdawania sobie z tego sprawy).

Zbieraj feedback bez przepisywania wszystkiego. Dodaj krótką ścieżkę zgłaszania problemu w dokumentacji i taguj każde zgłoszenie endpointem, request id i wersją klienta. Gdy coś naprawisz, preferuj zmiany addytywne: nowe pola, nowe opcjonalne parametry lub nowy endpoint zamiast łamania istniejącego zachowania.

Następne kroki: napisz jednostronicową specyfikację API z zasobami, planem wersjonowania, zasadami paginacji i kształtem błędów. Potem przygotuj dokumentację i malutkie SDK startujące od auth plus 2–3 podstawowych endpointów. Jeśli chcesz iść szybciej, możesz szkicować specyfikację, dokumentację i starter SDK z planu opartego na czacie używając narzędzi takich jak Koder.ai (tryb planowania jest pomocny, by uporać się z endpointami i przykładami zanim wygenerujesz kod).

Często zadawane pytania

Ile endpointów powinienem wystawić w moim pierwszym publicznym API?

Rozpocznij od 5–10 endpointów, które odwzorowują rzeczywiste akcje klientów.

Dobra zasada: jeśli nie potrafisz wyjaśnić zasobu w jednym zdaniu (czym jest, kto jest jego właścicielem, jak się go używa), trzymaj go prywatnie, dopóki nie nauczysz się więcej z rzeczywistego użycia.

Z jakich zasobów powinienem zacząć dla API SaaS?

Wybierz mały zestaw stabilnych rzeczowników (zasobów), których klienci faktycznie używają w rozmowie, i trzymaj ich nazwy stabilne, nawet jeśli zmienia się twoja baza danych.

Typowe startowe zasoby dla SaaS to users, organizations, projects i events — dodawaj kolejne dopiero, gdy pojawi wyraźne zapotrzebowanie.

Jakich metod HTTP powinienem używać i dlaczego to ma znaczenie?

Używaj standardowych znaczeń i bądź konsekwentny:

  • GET = odczyt (bez efektów ubocznych)
  • POST = tworzenie lub rozpoczęcie akcji
  • PATCH = częściowa aktualizacja
  • DELETE = usunięcie lub wyłączenie

Główna korzyść to przewidywalność: klienci nie powinni zgadywać, co robi metoda.

Czy powinienem wersjonować API w URL czy w nagłówkach?

Domyślnie wybierz wersjonowanie w URL, np. /v1/....

Łatwiej to zobaczyć w logach i zrzutach ekranu, prostsze do debugowania z klientami i ułatwia uruchamianie v1 i v2 obok siebie przy zmianach łamiących kompatybilność.

Co liczy się jako zmiana łamiąca kompatybilność w API?

Zmiana jest łamiąca, jeśli poprawny klient może przestać działać bez zmiany swojego kodu. Typowe przykłady:

  • Zmiana nazwy pola
  • Zmiana typu pola lub jego znaczenia
  • Usunięcie pola lub endpointu, na którym klienci polegają
  • Uczynienie wcześniej opcjonalnego pola wymaganym
  • Zmiana zasad autoryzacji lub domyślnych uprawnień

Dodanie nowego opcjonalnego pola zwykle jest bezpieczne.

Jaka jest realistyczna polityka deprecjacji dla API v1?

Utrzymaj prostotę:

  • Ogłoś deprecjację wcześnie
  • Zwróć jasne ostrzeżenie w odpowiedziach (i/lub w dokumentacji)
  • Podaj ostateczną datę wyłączenia

Praktyczny domyślny okres dla pierwszego API to 90 dni, żeby klienci mieli czas na migrację bez paniki.

Czy powinienem używać paginacji strony/limit czy cursor?

Wybierz jeden wzorzec i stosuj go do wszystkich list.

  • Użyj page/limit, gdy zbiory są małe i użytkownicy często przechodzą do strony 3.
  • Użyj cursor, gdy listy rosną, pojawiają się nowe pozycje często, lub są rozbudowane filtry.

Zawsze zdefiniuj domyślne sortowanie i tie-breaker (np. created_at + id), żeby wyniki nie skakały między zapytaniami.

Jaki limit rate powinienem ustawić i co zwracać przy 429?

Zacznij od jasnego limitu na klucz (np. 60 zapytań/min z możliwością krótkiego burstu), a potem dostosuj go do realnego ruchu.

Przy zwracaniu 429 podaj nagłówki:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset
  • Retry-After

To sprawia, że retry są przewidywalne i zmniejsza liczbę zgłoszeń do supportu.

Jak powinna wyglądać dobra odpowiedź z błędem w API?

Używaj jednego formatu błędu wszędzie (w tym dla 500). Praktyczny kształt:

  • code (stabilny identyfikator)
  • message (czytelny dla człowieka)
  • details (błędy na poziomie pól)
  • request_id (do wsparcia)

Utrzymuj też spójność kodów statusu (400/401/403/404/409/429/500), aby klienci mogli obsługiwać błędy poprawnie.

Jak opublikować dokumentację i małe SDK bez nadmiernego komplikowania?

Jeśli szybko generujesz wiele endpointów (np. z Koder.ai), trzymaj publiczną powierzchnię małą i traktuj ją jako długoterminowy kontrakt.

Zrób przed uruchomieniem:

  • po jednym realistycznym przykładzie request+response na endpoint
  • zablokuj zasady paginacji i kształt błędów
  • dodaj idempotency keys dla ważnych POST
  • zrób „fake client” wewnętrznie, żeby zobaczyć, gdzie jest nieintuicyjnie

Następnie opublikuj małe SDK, które pomaga w auth, timeoutach, retry dla bezpiecznych zapytań i paginacji — bez ukrywania mechaniki HTTP.

Related posts