Oprettelse af REST-mikrotjenester med Javalin

1. Introduktion

Javalin er en let webramme skrevet til Java og Kotlin. Det er skrevet oven på Jetty-webserveren, hvilket gør den yderst effektiv. Javalin er modelleret tæt fra koa.js, hvilket betyder, at den er skrevet fra bunden for at være enkel at forstå og bygge videre på.

I denne vejledning gennemgår vi trin til opbygning af en grundlæggende REST-mikroservice ved hjælp af denne lette ramme.

2. Tilføjelse af afhængigheder

For at oprette en grundlæggende applikation har vi kun brug for en afhængighed - Javalin selv:

 io.javalin javalin 1.6.1 

Den aktuelle version kan findes her.

3. Opsætning af Javalin

Javalin gør det let at opsætte en grundlæggende applikation. Vi begynder med at definere vores hovedklasse og oprette en simpel “Hello World” -applikation.

Lad os oprette en ny fil i vores basispakke kaldet JavalinApp.java.

Inde i denne fil opretter vi en hovedmetode og tilføjer følgende for at oprette en grundlæggende applikation:

Javalin app = Javalin.create () .port (7000) .start (); app.get ("/ hej", ctx -> ctx.html ("Hej, Javalin!");

Vi opretter en ny forekomst af Javalin, der får den til at lytte på port 7000 og derefter starte applikationen.

Vi opretter også vores første slutpunkt, der lytter til en anmodning på /Hej slutpunkt.

Lad os køre denne applikation og besøge // localhost: 7000 / hej for at se resultaterne.

4. Oprettelse af en UserController

Et "Hello World" -eksempel er fantastisk til at introducere et emne, men det er ikke gavnligt for en reel applikation. Lad os se på en mere realistisk brugssag for Javalin nu.

Først skal vi oprette en model af det objekt, vi arbejder med. Vi starter med at oprette en pakke kaldet bruger under rodprojektet.

Derefter tilføjer vi et nyt Bruger klasse:

public class User {public final int id; offentlig endelig Navn på streng; // konstruktører}

Vi er også nødt til at oprette vores dataadgangsobjekt (DAO). Vi bruger et objekt i hukommelsen til at gemme vores brugere i dette eksempel.

Vi opretter en ny klasse i bruger pakket kaldet UserDao.java:

klasse UserDao {private listebrugere = Arrays.asList (ny bruger (0, "Steve Rogers"), ny bruger (1, "Tony Stark"), ny bruger (2, "Carol Danvers")); privat statisk UserDao userDao = null; privat UserDao () {} statisk UserDao-forekomst () {hvis (userDao == null) {userDao = ny UserDao (); } returner userDao; } Valgfri getUserById (int id) {returnere brugere.stream () .filter (u -> u.id == id). FindAny (); } Iterable getAllUsernames () {return users.stream () .map (user -> user.name) .collect (Collectors.toList ()); }}

Implementering af vores DAO som en singleton gør det lettere at bruge i eksemplet. Vi kunne også erklære det som et statisk medlem af vores hovedklasse eller bruge afhængighedsinjektion fra et bibliotek som Guice, hvis vi ville.

Endelig vil vi oprette vores controller-klasse. Javalin giver os mulighed for at være meget fleksible, når vi erklærer vores rutehåndterere, så dette er kun en måde at definere dem på.

Vi opretter en ny klasse kaldet UserController.java i bruger pakke:

public class UserController {public static Handler fetchAllUsernames = ctx -> {UserDao dao = UserDao.instance (); Iterable allUsers = dao.getAllUsernames (); ctx.json (allUsers); }; offentlig statisk håndterer fetchById = ctx -> {int id = Integer.parseInt (Objects.requireNonNull (ctx.param ("id"))); UserDao dao = UserDao.instance (); Brugerbruger = dao.getUserById (id); hvis (bruger == null) {ctx.html ("Ikke fundet"); } andet {ctx.json (bruger); }}; }

Ved at erklære håndtererne som statisk, sikrer vi, at controlleren selv ikke har nogen tilstand. Men i mere komplekse applikationer vil vi muligvis gemme tilstand mellem anmodninger, i hvilket tilfælde vi bliver nødt til at fjerne den statiske modifikator.

Bemærk også, at enhedstest er sværere med statiske metoder, så hvis vi ønsker det testniveau, skal vi bruge ikke-statiske metoder.

5. Tilføjelse af ruter

Vi har nu flere måder at hente data fra vores model på. Det sidste trin er at udsætte disse data via REST-slutpunkter. Vi skal registrere to nye ruter i vores hovedapplikation.

Lad os tilføje dem til vores vigtigste applikationsklasse:

app.get ("/ brugere", UserController.fetchAllUsernames); app.get ("/ brugere /: id", UserController.fetchById);

Efter kompilering og kørsel af applikationen kan vi stille en anmodning til hvert af disse nye slutpunkter. Opkald // localhost: 7000 / brugere viser alle brugere, og opkald // localhost: 7000 / brugere / 0 får det enkelte bruger-JSON-objekt med id 0. Vi har nu en mikroservice, der giver os mulighed for at hente Bruger data.

6. Udvidelse af ruter

Hentning af data er en vigtig opgave for de fleste mikrotjenester.

Vi skal dog også være i stand til at gemme data i vores datalager. Javalin leverer det fulde sæt stihåndterere, der er nødvendige for at opbygge tjenester.

Vi så et eksempel på ovenfor, men PATCH, POST, SLET, og SÆTTE er også mulige.

Også, hvis vi inkluderer Jackson som en afhængighed, kan vi automatisk analysere JSON-anmodningsorganer i vores modelklasser. For eksempel:

app.post ("/") {ctx -> Brugerbruger = ctx.bodyAsClass (User.class); }

ville give os mulighed for at få fat i JSON Bruger objekt fra anmodningsorganet og oversætte det til Bruger modelobjekt.

7. Konklusion

Vi kan kombinere alle disse teknikker for at gøre vores mikroservice.

I denne artikel så vi, hvordan man konfigurerer Javalin og bygger en simpel applikation. Vi talte også om, hvordan man bruger de forskellige HTTP-metodetyper til at lade klienter interagere med vores service.

For mere avancerede eksempler på, hvordan du bruger Javalin, skal du tjekke dokumentationen.

Som altid kan koden findes på GitHub.