Article
#Artykuł #IntegracjaIT

Projektowanie API z pomocą OpenAPI

Opublikował Marcin Ziemek w dniu 23-07-2022

Czy chciałbyś poznać metodę projektowania API z wykorzystaniem specyfikacji OpenAPI? Z tego tekstu dowiesz się czym jest specyfikacja OpenAPI oraz jak ją wykorzystać do projektowania API.

Czym jest OpenAPI?

Specyfikacja OpenAPI (OAS) jest to standard wykorzystywany do opisu API. OAS jest niezależna od języka programowania. Standard jest łatwy do interpretacji i zrozumienia przez ludzi i komputery. API zgodne z OpenAPI definiujemy w YAML lub JSON.

W dalszej części artykuły będę odwoływał się do standardu OpenAPI w wersji 3.0.3 (https://spec.openapis.org/oas/v3.0.3) . Z najnowszą wersją możesz zapoznać się na stronie standardu OpenAPI (https://www.openapis.org/) .

Specyfikacja OpenAPI określa strukturę obiektów, ich typ, opis czy wymagalność. Zgodnie ze specyfikacją OpenAPI minimalna definicja API ma postać

Rysunek 1. Minimalna definicja API zgodna z OpenAPI

Zajrzyjmy jeszcze do specyfikacji, aby przeanalizować jak to odczytać.

W specyfikacji https://spec.openapis.org/oas/v3.0.3 możemy znaleźć definicję głównego obiektu OpenAPI Object.

Rysunek 2. Definicja OpenAPI Object ze specyfikacji OAS3 (Źródło: https://spec.openapis.org/oas/v3.0.3)

Wymagane pola to:
  • openapi, który jest typu string
  • info, typu Info
  • paths, typu Paths

Przeanalizujmy zatem definicję obiektu Info.

Rysunek 3. Definicja Info Object ze specyfikacji OAS3 (Źródło: https://spec.openapis.org/oas/v3.0.3)

Wymagane pola w Info to:
  • title, typu string
  • version, typu string

Spójrzmy jeszcze na definicję Paths.

Rysunek 4. Definicja Paths Object ze specyfikacji OAS3 (Źródło: https://spec.openapis.org/oas/v3.0.3)

Zgodnie z opisem Paths może być puste.

Zatem minimalna postać definicji API zgodna ze standardem OpenAPI ma postać

Rysunek 5. Minimalna definicja API zgodna z OpenAPI

Projektowanie API poprzez analizę ręczną specyfikacji jest czasochłonne, dlatego warto wykorzystać jedno z narzędzi, które podpowiada składnię, waliduje poprawność przygotowanego dokumentu oraz wizualizuje zaprojektowane API.

Najpopularniejszym narzędziem służącym do tego jest Swagger.

Do czego służy Swagger?

Swagger (https://swagger.io/) jest zestawem narzędzi ułatwiającym projektowanie, implementację, testowanie oraz dokumentowanie API.

Składa się z narzędzi takich jak:
  • Swagger Editor – narzędzie ułatwiające projektowanie API zgodnie z OpenAPI
  • Swagger UI – narzędzie prezentujące zaprojektowane API
  • Swagger Codegen – narzędzie generujące kod klienta oraz serwera na podstawie zaprojektowanego API
  • Swagger Hub – platformę do projektowania oraz dokumentowania API przeznaczona dla zespołów i firm

Zaprojektujmy pierwsze API w Swagger Editor (https://editor.swagger.io/) .

Rysunek 6. Minimalna definicja API zgodna z OAS3 w narzędziu Swagger Editor

W narzędziu Swagger Editor z lewej strony widzimy projekt API w YAML (możemy również wykorzystać JSON) natomiast po prawej stronie wizualizację w Swagger UI.

Zaprojektujmy teraz bardziej skomplikowane API zgodne z OpenAPI.

Projekt API dla domeny Klienta

Zaprojektujemy wspólnie API dla domeny Klienta w przykładowym sklepie.

Rysunek 7. API dla domeny Klienta przykładowego sklepu

API będzie umożliwiało:
  • pobranie listy klientów
  • pobranie szczegółów konkretnego klienta
  • dodanie klienta
  • modyfikację danych klienta
  • usunięcie klienta
W tym celu zaprojektujemy zasób customers.
  • /v1/customers – będzie umożliwiał pobranie listy klientów oraz utworzenie nowego klienta
  • /v1/customers/{customerId} – będzie umożliwiał pobranie szczegółów konkretnego klienta, aktualizację danych klienta oraz jego usunięcie

Wykorzystamy operacje HTTP GET w celu pobrania, POST w celu utworzenia, PUT do aktualizacji i DELETE do usunięcia zasobów.

Tak zaprojektowany zasób musimy umieścić w sekcji paths zgodnie z OpenAPI.

Rysunek 8. Zaprojektowane zasoby API

W kolejnym kroku zaprojektujmy model danych komunikacji, który wykorzystamy w API.

Niech klient określony będzie atrybutami imię, nazwisko, adres email oraz adres klienta, gdzie tylko adres klienta nie jest wymagany. Adres składa się z ulicy, numeru mieszkania, miasta, kodu pocztowego i kraju. Dodatkowo wprowadźmy obiekt lista klientów.

A teraz zaprojektujmy obiekty klienta, adresu oraz listy klientów zgodnie z OpenAPI w sekcji components.

Rysunek 9. Zaprojektowane komponenty API

W naszym rozwiązaniu zastosujemy uproszczenie. Gdy pobieramy listę klientów wówczas danych może być bardzo dużo. Popularnym rozwiązaniem poprawiającym wydajność jest wykorzystanie stronicowania wyników. W naszym przykładzie nie wprowadzamy stronicowania.

W kolejnym kroku zaprojektujemy szczegóły wprowadzonych wcześniej operacji.

Rozpocznijmy od operacji pobrania listy klientów. W celu pobrania listy wszystkich klientów nie musimy przekazać w żądaniu żadnych parametrów.

Dla operacji zdefiniowaliśmy możliwe kody odpowiedzi: 200, 400, 401, 500 oraz 503 zgodnie z protokołem HTTP. W przypadku kodu 200 zostanie zwrócona lista klientów. W pozostałych przypadkach kod wraz z informacją o błędzie.

Rysunek 10. Zaprojektowane pobranie listy klientów

Gdy korzystamy z Swagger Editor wówczas z prawej strony widoczna jest wizualizacja zaprojektowanego zasobu.

Rysunek 11. Zaprojektowane pobranie listy klientów widoczne w Swagger Editor i UI

W kolejnym kroku zaprojektujemy operację tworzenia nowego klienta. W tym przypadku musimy przekazać w żądaniu dane klienta, który ma zostać utworzony.

W odpowiedzi otrzymamy kod 201, 400, 401, 500 lub 503. Dla kodu 201, który będzie informował o poprawnym utworzeniu klienta dodatkowo przekażemy w odpowiedzi w sekcji headers lokalizację utworzonego zasobu.

Rysunek 12. Zaprojektowane utworzenie klienta

Następnie przejdźmy do zaprojektowania pobrania szczegółów klienta. W tym przypadku wprowadzimy parametr customerId, który zostanie przekazany w ścieżce URL. W przypadku sukcesu szczegóły klienta zostaną zwrócone z kodem 200 HTTP.

Rysunek 13. Zaprojektowane pobranie szczegółów klienta

Kolejnym krokiem jest zaprojektowanie operacji aktualizacji danych klienta. W tym celu wykorzystamy operację PUT. W żądaniu musimy przekazać szczegóły aktualizowanego klienta natomiast w ścieżce URL identyfikator klienta (customerId).

W odpowiedzi otrzymamy kod informujący o statusie operacji: 200, 400, 401, 404, 500 lub 503.

Rysunek 14. Zaprojektowana aktualizacja klienta

Aby umożliwić usunięcie klienta wykorzystamy operację DELETE. Musimy przekazać identyfikator klienta, którego chcemy usunąć. Podobnie jak dla operacji pobrania szczegółów klienta i aktualizacji klienta zostanie on przekazany w ścieżce URL.

W przypadku operacji usunięcia klienta zostanie zwrócony tylko kod odpowiedzi 200, 400, 401, 404, 500 lub 503.

Rysunek 15. Zaprojektowane usunięcie klienta

W naszym API wykorzystamy tokeny JWT w celu zapewnienia bezpieczeństwa. Autoryzację ustawimy globalnie dla wszystkich zasobów. W tym celu dodamy definicję obiektu JwtAuthToken w sekcji compoents oraz w uzupełnimy sekcję security.

Rysunek 16. Zaprojektowane bezpieczeństwo API

Przygotowane przez nas API w narzędziu Swagger zostało zaprezentowane na rysunku poniżej.

Możesz również pobrać zaprojektowane API klikając w LINK .

Rysunek 17. Zaprojektowane API dla domeny Klienta