Úvod do protokolu Akka HTTP

1. Prehľad

V tomto tutoriáli sa pomocou modelov Akka & Stream od Akky dozvieme, ako nastaviť Akku na vytvorenie HTTP API, ktoré poskytuje základné operácie CRUD.

2. Maven závislosti

Na začiatok sa pozrime na závislosti, ktoré sú potrebné na začatie práce s protokolom Akka HTTP:

 com.typesafe.akka akka-http_2.12 10.0.11 com.typesafe.akka akka-stream_2.12 2.5.11 com.typesafe.akka akka-http-jackson_2.12 10.0.11 com.typesafe.akka akka-http- testkit_2.12 10.0.11 test 

Najnovšiu verziu týchto knižníc Akka samozrejme môžeme nájsť v Maven Central.

3. Vytvorenie herca

Ako príklad zostavíme rozhranie HTTP API, ktoré nám umožní spravovať zdroje používateľov. API bude podporovať dve operácie:

  • vytvorenie nového používateľa
  • načítava sa existujúci užívateľ

Skôr ako môžeme poskytnúť HTTP API, budeme musieť implementovať aktéra, ktorý poskytuje operácie, ktoré potrebujeme:

trieda UserActor rozširuje AbstractActor {private UserService userService = nový UserService (); statické rekvizity rekvizity () {návrat Props.create (UserActor.class); } @Override public Príjem createReceive () {návrat receiveBuilder () .match (CreateUserMessage.class, handleCreateUser ()) .match (GetUserMessage.class, handleGetUser ()) .build (); } súkromné ​​FI.UnitApply handleCreateUser () {návrat createUserMessage -> {userService.createUser (createUserMessage.getUser ()); sender () .tell (new ActionPerformed (String.format ("Používateľ% s bol vytvorený.", createUserMessage.getUser (). getName ())), getSelf ()); }; } súkromné ​​FI.UnitApply handleGetUser () {návrat getUserMessage -> {sender (). tell (userService.getUser (getUserMessage.getUserId ()), getSelf ()); }; }}

V zásade rozširujeme AbstractActor triedy a implementáciu jej createReceive () metóda.

V rámci createReceive (), sme mapovanie typov prichádzajúcich správ na metódy, ktoré spracúvajú správy príslušného typu.

Typy správ sú jednoduché serializovateľné triedy kontajnerov s niektorými poľami, ktoré popisujú určitú operáciu. GetUserMessage a má jediné pole ID používateľa na identifikáciu používateľa na načítanie. CreateUserMessage obsahuje a Používateľ objekt s údajmi používateľa, musíme vytvoriť nového používateľa.

Neskôr uvidíme, ako preložiť prichádzajúce požiadavky HTTP do týchto správ.

Nakoniec všetky správy delegujeme na adresu a UserService inštancia, ktorá poskytuje obchodnú logiku potrebnú na správu objektov trvalých používateľov.

Nezabudnite tiež na rekvizity () metóda. Kým rekvizity () metóda nie je nevyhnutná na rozšírenie AbstractActor, bude sa to hodiť neskôr pri vytváraní ActorSystem.

Ak sa chcete podrobnejšie rozprávať o hercoch, pozrite si náš úvod k hercom Akka.

4. Definovanie smerov HTTP

Mať herca, ktorý za nás robí skutočnú prácu, zostáva nám len poskytnúť HTTP API, ktoré deleguje prichádzajúce HTTP požiadavky na nášho herca.

Akka používa koncepciu trás na opísanie HTTP API. Pre každú operáciu potrebujeme trasu.

Aby sme vytvorili server HTTP, rozšírime triedu framework HttpApp a implementovať trás metóda:

trieda UserServer rozširuje HttpApp {private final ActorRef userActor; Časový limit časového limitu = nový časový limit (Duration.create (5, TimeUnit.SECONDS)); UserServer (ActorRef userActor) {this.userActor = userActor; } @Override public Route routes () {return path ("users", this :: postUser) .orElse (path (segment ("users"). Slash (longSegment ()), id -> route (getUser (id)) )); } súkromná trasa getUser (Long id) {return get (() -> {CompletionStage user = PatternsCS.ask (userActor, new GetUserMessage (id), timeout) .thenApply (obj -> (voliteľné) obj); návrat onSuccess (() -> používateľ, vykonaný -> {if (provádí.isPresent ()) návrat dokončený (StatusCodes.OK, prevedený.get (), Jackson.marshaller ()); iný návrat dokončený (StatusCodes.NOT_FOUND); }); }); } súkromná trasa postUser () {spiatočná trasa (post (() -> entita (Jackson.unmarshaller (User.class), užívateľ -> {CompletionStage userCreated = PatternsCS.ask (userActor, new CreateUserMessage (user), timeout) .thenApply (obj -> (ActionPerformed) obj); návrat onSuccess (() -> userCreated, vykonaný -> {návrat dokončený (StatusCodes.CREATED, vykonaný, Jackson.marshaller ());});}))); }} 

Teraz je tu pomerne veľa variácií, ale všimnite si, že sa riadime rovnakým vzorom ako predtým mapovacie operácie, tentoraz ako trasy. Poďme to trochu rozobrať.

V rámci getUser (), jednoducho zabalíme ID prichádzajúceho používateľa do správy typu GetUserMessage a preposlať túto správu našej userActor.

Hneď ako herec správu spracuje, naÚspech sa volá psovod, v ktorom sme kompletný požiadavku HTTP zaslaním odpovede s určitým stavom HTTP a určitým telom JSON. Jacksonovho Marshallera používame na serializáciu odpovede od herca do reťazca JSON.

V rámci postUser (), robíme veci trochu inak, pretože v požiadavke HTTP očakávame telo JSON. Používame entita () metóda na mapovanie prichádzajúceho tela JSON do a Používateľ objekt pred zabalením do a CreateUserMessage a odovzdať to nášmu hercovi. Znovu používame Jackson na mapovanie medzi Java a JSON a naopak.

Odkedy HttpApp očakáva, že poskytneme jediný Trasa kombinujeme obe cesty do jednej v rámci objektu trás metóda. Tu používame cesta smernica konečne poskytne cestu URL, na ktorej by malo byť naše API dostupné.

Viažeme trasu poskytovanú používateľom postUser () na cestu / používateľov. Pokiaľ prichádzajúca požiadavka nie je POST požiadavkou, Akka automaticky prejde do alebo iný vetva a rátajte s tým, že cesta bude / používatelia / a metódu HTTP GET.

Ak je metóda HTTP GET, požiadavka bude preposlaná getUser () trasa. Ak užívateľ neexistuje, Akka vráti stav HTTP 404 (Nenašiel sa). Ak metóda nie je ani POST, ani GET, Akka vráti stav HTTP 405 (metóda nie je povolená).

Ďalšie informácie o tom, ako definovať trasy HTTP pomocou Akky, nájdete v dokumentoch Akky.

5. Spustenie servera

Akonáhle sme vytvorili HttpApp implementácia, ako je uvedené vyššie, môžeme spustiť náš server HTTP s niekoľkými riadkami kódu:

public static void main (String [] args) hodí Exception {ActorSystem system = ActorSystem.create ("userServer"); ActorRef userActor = system.actorOf (UserActor.props (), "userActor"); Server UserServer = nový UserServer (userActor); server.startServer ("localhost", 8080, systém); }

Jednoducho vytvoríme ActorSystem s jediným aktérom typu UserActor a spustite server na localhost.

6. Záver

V tomto článku sme sa dozvedeli o základoch protokolu Akka HTTP na príklade, ktorý ukazuje, ako nastaviť server HTTP a vystaviť koncové body na vytváranie a načítanie zdrojov, podobne ako REST API.

Tu uvedený zdrojový kód nájdete ako obvykle na GitHub.