Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Uwolnij swoje API od bólu z Smithy4s

Uwolnij swoje API od bólu z Smithy4s

W życiu większości backendowych projektów przychodzi moment, gdy trzeba zdefiniować jakieś API. Implementujemy dla nich route'y, dokumentujemy je, czasem piszemy klienta. Wykonujemy praktycznie tę samą pracę kilka razy - w naszych endpointach są wciąż te same ścieżki, a jednak nie mamy "jednego źródła prawdy". I wtedy wchodzi Smithy, cały na biało!
W prezentacji pokażę, jak Smithy (i smithy4s) umożliwia definiowanie API w jednym miejscu i budowanie dla niego serwera, klienta, a także CLI - w przyjazny dla Scali i jej toolingu sposób. Porównam też wady i zalety rozwiązania, jakie oferuje Smithy, z alternatywami (OpenAPI, tapir, http4s-rho etc.).

Linki ze slajdu z linkami:

- https://linktr.ee/kubukoz
- https://smithy.io
- https://disneystreaming.github.io/smithy4s
- https://youtu.be/3GpZzu4guTE
- https://youtu.be/kvBX9u6uRaE
- https://blog.indoorvivants.com/2022-06-10-smithy4s-fullstack-part-1

Jakub Kozłowski

January 23, 2023
Tweet

More Decks by Jakub Kozłowski

Other Decks in Programming

Transcript

  1. Uwolnij Uwolnij swoje API od swoje API od bólu z

    bólu z smithy4s smithy4s Jakub Kozłowski Jakub Kozłowski
  2. Plan na dziś Plan na dziś częste błędy i problemy:

    przyczyny i skutki – smithy: czym jest, o co w tym chodzi – jak Smithy pomaga rozwiązać te problemy –
  3. Błędy zaczynają się od nas. Przede wszystkim: nie jesteśmy idealni

    – nie jesteśmy maszynami – zdarzają się pomyłki –
  4. Komunikacja Komunikacja Mamy błędy w komunikacji. W komunikacji jest naprawdę

    bardzo dużo okazji do pomyłek. decydujemy co trzeba zrobić i dlaczego. często już tutaj zdarza się nie dogadać - komunikacja jest po prostu komunikacja jest po prostu TRUDNA TRUDNA. Jest to z wielu powodów: A nawet nie zaczęliśmy jeszcze pisać kodu! Co może wyniknąć z takich pomyłek? Rozmawiamy z innymi zespołami – naszymi stakeholderami – użytkownikami – bariery językowe, kulturowe – implicit bias – opinie – błędy! Może po prostu nie usłyszeliśmy dokładnie całego zdania, albo zapomnieliśmy czegoś zanim planowaliśmy to zapisać. –
  5. Źle zrozumiane Źle zrozumiane wymagania wymagania Co do tego, co

    ma się znaleźć w naszym API, albo jak my mamy używać czyjegoś.
  6. Rozwiązywanie Rozwiązywanie złego problemu złego problemu I najgorsze Zdarza się,

    że po prostu zabieramy się za rozwiązywanie problemu, który nie istnieje, albo budujemy rozwiązanie które nie ma się nijak do tego problemu, który jest. Ogromna strata czasu (wielu osób i zespołów)
  7. I to nawet nie I to nawet nie wszystko! wszystko!

    Wiele innych problemów może wyniknąć z błędów i niejasności w komunikacji, ale te wymienione powinny dać Wam jakiś obraz możliwych komplikacji. Ale wyobraźmy sobie, że udało nam się przebrnąć przez fazę planowania, i zabieramy się do implementacji naszego API!
  8. Pomyłki przy Pomyłki przy pisaniu pisaniu literówki – kod klienta

    się rozjeżdża – kod serwera się rozjeżdża – klient/serwer do siebie nie pasują – ten sam endpoint definiowany w każdym kliencie/serwerze, więc problem mnoży się –
  9. Problemy z Problemy z dokumentacją dokumentacją nie ma jej, albo

    – Nie zgadza się z tym, co robi serwer – Zdarza się częściej, niż by się chciało – Nawet w dojrzałych technicznie organizacjach –
  10. Utrudnienia w Utrudnienia w utrzymywaniu utrzymywaniu ciężko wykryć zmiany naruszające

    kompatybilność – reszta zespołów nie wprowadza koniecznych zmian – ciężko np. usunąć stare API które od dawna jest "deprecated" –
  11. Język Język opisu opisu interfejsu interfejsu (IDL - (IDL -

    Interface Interface definition definition language) language) operation GetWeather { input := { @required city: String } output := { @required weather: Weather } } structure Weather { @required degrees: Integer details: String } Niewielki język, ograniczona ilość feature'ów – Rozszerzalny dla użytkowników – Nie ma tu detali np. HTTP (ale da się je dodać) –
  12. Stworzony przez AWS Stworzony przez AWS używany wewnątrz do budowania

    wszystkich API – używany w SDK (Java, JS, Rust...) – używany też w SXM, DSS –
  13. Niezależny od Niezależny od protokołu protokołu nie tylko HTTP, nie

    tylko REST – najpierw modelujemy domenę, implementacja to detal – zależy od interpretacji – możemy budować własne protokoły/transporty – np. Jest otwarty PR do bsp definiujący ten protokół w Smithy i generujący kod do bsp4j –
  14. Czytelny i zwięzły Czytelny i zwięzły dla maszyny i dla

    człowieka Czytelny dla maszyny, bo jest deklaratywny: Da się to opisać jako struktura danych, więc można analizować bez rozumienia konceptów takich jak "if". W przypadku np. Http4s, nawet wtedy nie byłoby to możliwe. Czytelny dla człowieka, bo ma prostą składnię bez zbędnych informacji dla maszyny: – umożliwia precyzyjną interpretację – da się generować kod – łatwe budowanie/rozszerzanie narzędzi – można ustalać standardy i sprawdzać czy API się ich trzymają, np. – spójne wersjonowanie API w całej firmie – spójny kształt odpowiedzi z błędami – dla człowieka: – da się to czytać w Pull Requestach – da się to pisać bez specjalnego edytora – jeśli reszta nie przekonuje, przynajmniej nie jest to YAML –
  15. Przykład HTTP Przykład HTTP namespace hello use alloy#simpleRestJson @simpleRestJson service

    WeatherService { operations: [GetWeather] } @http( method: "GET", uri: "/weather/{city}" ) @readonly operation GetWeather { ... }
  16. Ułatwia Ułatwia komunikację komunikację Język precyzyjnie opisuje API, więc nie

    ma miejsca na nie zrozumienie drugiej osoby – Przegapienie pola w dyskusji zostanie zauważone w pull requeście definiującym API – W podejściu API-first możemy łatwo pracować z osobami nie znającymi naszego języka programowania i bibliotek –
  17. Jedno źródło Jedno źródło prawdy prawdy Dokumentacja, klient i serwer

    nie "rozjadą" się (dzięki temu że maszyny mogą to czytać) – Definicję możemy dystrybuować przez udostępnianie plików np. GitHub assety, JARy w artifactory albo wtyczka do build toola (sbt) – nie tylko łatwe do napisania, ale też do utrzymania –
  18. Niezależny od Niezależny od języka języka Ja wiem, że kochamy

    Scalę i chcielibyśmy żeby wszyscy jej używali – ale nie tylko Scalą projekt żyje ;) – np. Urządzenia mobilne, frontend – abstrakcja nie cieknie, API nie jest zależne od konwencji w języku. Nie musimy znać bibliotek. – można zapomnieć o eDSLach routingowych (implicity, makra, pattern matching) –
  19. Smithy4s Smithy4s Biblioteka do generowania kodu i pracy z Smithy

    w Scali – Generuje czytelny kod i metadane z definicji w Smithy – Zaprojektowana dla rozszerzalności (Bez zależności w core) – Integruje się z http4s, można budować własne integracje – Klient/serwer/CLI za darmo –
  20. Serwer (routes) Serwer (routes) val impl: WeatherService[IO] = ... def

    run: IO[Unit] = SimpleRestJsonBuilder .routes(impl) .resource .flatMap { routes => // normal http4s stuff from now on EmberServerBuilder .default[IO] .withHttpApp(routes.orNotFound) .build } .useForever
  21. Linki Linki Slajdy: będą na – linktr.ee/kubukoz kontakt: też ;)

    – – smithy.io – disneystreaming.github.io/smithy4s – Scaling APIs with Smithy – Revisiting visitors: a talk about generalising serialisation – smithy4s fullstack (blogpost series)
  22. See also See also Smithy Playground Smithy Playground github.com/kubukoz/smithy-playground pomijając

    czy jest to przydatne, potrzebne czy wartościowe w jakikolwiek sposób – fajna zabawa i dało mi możliwość nauczenia się wielu rzeczy, np. Budowania serwerów LSP – o tym też może kiedyś będzie prezentacja – zapraszam do subskrypcji ;) –
  23. OpenAPI OpenAPI ograniczone do HTTP – ciężko budować na tym

    narzędzia (np. Brak walidacji w standardowych narzędziach dla JVM) – generowanie kodu to tak naprawdę bootstrap dla projektu – podejście do codegenu nie jest tym czego potrzebuję – jest wspierane w standardowych narzędziach Smithy. Musimy tylko trochę to konfigurować jeśli definiujemy własny protokół. –
  24. tapir, endpoints4s, tapir, endpoints4s, Udash, http4s-rho ... Udash, http4s-rho ...

    ograniczają się do Scali – korzystają ze skomplikowanych feature's języka tj. Implicity, makra – (tapir kombinuje z generowaniem z openapi - brak postępu od ok. roku) – głównie HTTP, choć tapir powoli idzie w kierunku wsparcia gRPC – ale: aktualnie np. Tapir wspiera znacznie więcej frameworków. Choć dodanie nowego frameworka nie wymaga wielkiej ilości pracy, smithy4s część tej pracy załatwia już za nas. –
  25. gRPC, GraphQL, gRPC, GraphQL, RSocket... RSocket... te protokoły/specyfikacje mają specjalne

    zastosowania – np. graphql skupia się na zapytaniach o konkretne elementy i na grafach. IMO głównie przydatny dla klientów frontendowych/na urządzeniach użytkownika – mogą wymagać innego sposobu myślenia, innych narzędzi, a jednak REST/HTTP są teraz standardem i Smithy pozwala nam zacząć z tego punktu wyjścia i potencjalnie przenieść się na inny protokół później – nic nie stoi na przeszkodzie żeby wspierać nawet kilka protokołów naraz – możemy je "wywnioskować" z definicji w Smithy – np. Jak dana rzecz ma być reprezentowana w protobuf – warto wspomnieć o "apply" w smithy –