Złote zasady tworzenia API

Dzisiaj chciałbym Ci poopowiadać o złotych zasadach stworzenia API. Mam nadzieję, że poniższy tekst pomoże tworzyć rozwiązania przyjazne zarówno jego użytkownikom, jak i twórcom.. Zasady, o których będę opowiadał są uniwersalne, dlatego tylko trochę zahaczymy o kwestie związane z RESTful API. Jednocześnie zachęcam do zapoznania się z specyfikacją tego standardu.

Spójność

Pierwszą rzeczą, którą musimy sobie uświadomić jest to, że nie piszemy kodu dla naszej wewnętrznej chwały. Tworzymy API by udostępnić je innym. To właśnie użytkownicy wystawią nam opinie o naszym rozwiązaniu. Dlatego najważniejsza jest konsekwencja. Najprościej wyjaśnić to na przykładzie.
Załóżmy, że nasze API udostępnia dwie metody:

  • add-user
  • user-delete

brakuje tu jednej spójnej wizji, konsekwencji w nazywaniu endpointów.
Lepiej nazywać metody w jednej konwencji:

  • add-user
  • delete-user

Ewentualnie dzieląc na konkretne obszary:

  • user-add
  • user-delete.

Dane wejściowe

Tutaj najważniejsza jest również – konsekwencja. Jeżeli w pierwszej stworzonej metodzie, w nazwach parametrów zastosujesz camelCase, to musisz się już trzymać tego w tej konkretnej wersji. Postaw się w roli potencjalnego użytkownika Twojego rozwiązania. Jak byś się czuł, gdyby każda metoda wymagała od Ciebie nowego podejścia? Problematyczna jest literka „s” – userId i usersid to naprawdę nie jest to samo. Ja osobiście jestem zwolennikiem stosowania „s”.

Kolejną równie ważną rzeczą na jakiej powinieneś się skupić jest bezpieczeństwo. API jest punktem wejścia do systemu. Jeżeli tu przepuścisz niebezpieczny kod, to pozostaje tylko zaufanie, że twórcy komponentów, które wykorzystujesz, zabezpieczyli się przed taką ewentualnością. W innym przypadku, właśnie pozwoliłeś komuś na wejście do Twojego systemu. Po drugie: zrób to dla siebie. Atak może Cię zaskoczyć w najmniej oczekiwanym momencie. Na początek, zdefiniuj typy parametrów, w myśl zasady „jeżeli coś ma być int-em,to ma być intem i kropka”. Dzięki temu możemy już łatwo rzutować parametry wejściowe na zdefiniowane typy (jeśli używasz typowanego języka masz łatwiej :)). Jednym z podejść jest stworzenie klasy, której jedynym celem będzie wyłuskanie parametrów żądania i ich oczyszczenie. Absolutne minimum to zabezpieczenie się przed atakami z listy OWASP Top 10.

Dane wyjściowe

Zawsze musimy być pewni co wysyłamy w odpowiedzi na zapytanie, tak by w razie błędu, nie zdradzić struktury naszej aplikacji lub schematu bazy danych. Takie niedopatrzenie wygląda w oczach odbiorców mało profesjonalnie. Nie warto też ułatwiać pracy osobom, które chciałyby zrobić coś złego z naszym systemem.

Powinieneś dać użytkownikom łatwą możliwość określenia jaki skutek ma wywołać ich żądanie. Najprostszą metodą na to jest używanie kodów odpowiedzi HTTP… Innych niż 200 i 500 :)

Dodatkowo możemy zastosować komunikaty tekstowe. Trudniej je zmapować na konkretne zachowania systemu, dlatego powinny być tylko informacją uzupełniającą. Ja w swoich rozwiązaniach nie tłumaczę komunikatów zwrotnych. Zwracam je po angielsku.

Limity

O ile nie masz nieograniczonych zasobów, zastanów się nad określaniem maksymalnej ilości obsługiwanych żądań. Zacznij od wyznaczenia jakie maksima jesteś w stanie przyjąć, np. oparciu o specyfikację serwera. Następnie ustal limity, np. 60% – 70% górnego progu – przy takim podejściu zawsze zostaje zapas mocy na nieprzewidziane sytuacje.


Czekaj, stop!

Podoba Ci się to co tworzę? Jeśli tak to zapraszam Cię do zapisania się na newsletter:

Aby potwierdzić swoją subskrypcję, odbierz pocztę i kliknij w link potwierdzający:) jeśli maila nie ma to poczekaj chwile i/lub sprawdź folder spam/inne/oferty itp :)

Aby potwierdzić swoją subskrypcję, odbierz pocztę i kliknij w link potwierdzający:) jeśli maila nie ma to poczekaj chwile i/lub sprawdź folder spam/inne/oferty itp :)
a w ramach prezentu otrzymasz całkowicie za darmo, dwa dokumenty PDF „6 (nie zawsze oczywistych) błędów popełnianych podczas nauki programowania” który jest jednym z efektów ponad siedmioletniej pracy i obserwacji rozwoju niejednego programisty oraz „Wstęp do testowania w Pythonie”, będący wprowadzeniem do biblioteki PyTest.
Jeśli to Cię interesuje to zapraszam również na swoje social media.

Jak i do ewentualnego postawienia mi kawy :)

Kill switch

Czasami będziesz zmuszony wyłączyć daną funkcjonalność lub odciąć dostęp konkretnym osobom/aplikacjom. Powodów może być wiele, np. bezpieczeństwo (klient wysłał swoje hasło do wszystkich znajomych na FB) czy wydajność, bo aplikacja która korzysta z Twojego API właśnie się zapętla i wysyła setki żądań na sekundę, blokując całkowicie bazę danych. Jeżeli nie przygotujesz się na taką sytuację, najprawdopodobniej skończy się to dodawaniem na szybko if-a na produkcji.

A gdyby tak dodać prosty mechanizm zabezpieczający? W najprostszym przypadku może być to tabela w bazie danych, w której będziemy mieli datę początku i końca blokady oraz przyczynę. Trzy kolumny. Potem możesz przygotować proste narzędzie, które będzie dawało możliwość zarządzania blokadami.

„Panie gdzie mnie z tą logiką, toż to interfejs tylko…”

Twoje API nie powinno zawierać żadnej logiki biznesowej. Załóżmy, że musisz sprawdzić czy klient ma wykupiony dostęp do konkretnych usług. Znajdź w systemie moduł odpowiedzialny za uprawnienia i tam dopisz odpowiednie metody. W większych firmach możesz zlecić zaimplementowanie potrzebnego fragmentu odpowiedniemu zespołowi obsługującemu ten konkretny moduł.

Logi, wszędzie logi

O ile podczas developmentu możesz wszystko prześledzić w debuggerze, to na produkcji już nie jest tak wesoło. Dlatego absolutnym minimum jest logowanie kto, kiedy i jaką akcję wykonał. Kolejną rzeczą, którą powinniśmy zalogować są odpowiedzi do klienta w przypadku błędu. Dlaczego? Jeżeli klient dostanie komunikat o niepoprawnych danych wysyłanych do naszego API i je zlekceważy, będziemy mogli szybko odszukać przyczynę błędu. Tym sposobem zaoszczędzimy czas zarówno nasz, jak i naszych klientów.

Podsumowanie

Celem artykułu było przekazanie Ci kawałka swojego doświadczenia z wieloletniej pracy przy integracjach. Wiem, że część z omówionych tematów realizują gotowe biblioteki. Pytanie brzmi: czy jesteś świadom co dokładnie robią? Jeśli nie, może warto to wiedzieć? Jeśli czegoś brakuje Ci w tym co napisałem to nie krępuj się, napisz komentarz.

Autorem wpisu jest Łukasz Krawczyk, programista z kilkuletnim doświadczeniem, specjalizujący się w integracji i optymalizacji systemów informatycznych. A nade wszystko – czujny obserwator procesu dostarczania oprogramowania.

Dzięki za wizytę,
Mateusz Mazurek
Łukasz Krawczyk

Pokaż komentarze

  • Dodał bym jeszcze to, że trzeba utrzymywać aktualną dokumentację:)

  • Fajny artykuł Mateusz. Może byś napisał o API dla newbies. Chętnie bym poczytał czym jest API oraz jak się tworzy proste API w Python.

    Mam jakieś pojęcie o API ale bardzo podstawowe. Chętnie bym się dowiedział o tym więcej.

    Hej.

Ostatnie wpisy

Python 1.0 vs. 3.13: Co się zmieniło?

Cześć. Dziś luźny artykuł, bo dziś pobawimy się jedną z pierwszy wersji Pythona. Skompilujemy go i zobaczymy co tam w… Read More

1 tydzień ago

Podsumowanie: styczeń i luty 2025

Nowy rok czas zacząć! Więc lećmy z podsumowaniem. Nowy artykuł Nie uwierzycie, ale pojawił się na blogu nowy artykuł! Piszę… Read More

3 tygodnie ago

Just-in-time compiler (JIT) w Pythonie

Cześć! W Pythonie 3.13 dodano JITa! JIT, czyli just-in-time compiler to optymalizacja na która Python naprawdę długo czekał. Na nasze… Read More

1 miesiąc ago

Podsumowanie roku 2024

Cześć! Zapraszam na podsumowanie roku 2024. Książki W sumie rok 2024 był pod względem ilości książek nieco podobny do roku… Read More

1 miesiąc ago

Podsumowanie: wrzesień, październik, listopad i grudzień 2024

Podtrzymując tradycję, prawie regularnych podsumowań, zapraszam na wpis! Nie mogło obyć się bez Karkonoszy We wrześniu odwiedziłem z kolegą Karkonosze,… Read More

2 miesiące ago

Podsumowanie: maj, czerwiec, lipiec i sierpień 2024

Oj daaawnoo mnie tu nie było. Ale wakacje to był czas dużej liczby intensywnych wyjazdów i tak naprawdę, dopiero jakoś… Read More

6 miesięcy ago