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.
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:
brakuje tu jednej spójnej wizji, konsekwencji w nazywaniu endpointów.
Lepiej nazywać metody w jednej konwencji:
Ewentualnie dzieląc na konkretne obszary:
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.
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.
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.
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.
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ł.
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.
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.
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
Cześć! Zapraszam na krótkie podsumowanie kwietnia. Wyjazd do Niemiec A dokładniej pod granicę z Francją. Chrześnica miała pierwszą komunię. Po… Read More
Ostatnio tygodnie były tak bardzo wypełnione, że nie udało mi się napisać nawet krótkiego podsumowanie. Więc dziś zbiorczo podsumuję luty… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W styczniu przeczytałem "Homo Deus: Historia jutra". Książka łudząco podoba do wcześniejszej książki tego… Read More
Cześć! Zapraszam na podsumowanie roku 2023. Książki Zacznijmy od książek. W tym roku cel 35 książek nie został osiągnięty. Niemniej… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W grudniu skończyłem czytać Mein Kampf. Nudna książka. Ciekawsze fragmenty można by było streścić… Read More
Pokaż komentarze
Dodał bym jeszcze to, że trzeba utrzymywać aktualną dokumentację:)
Swagger pomoże :D
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.