Création de microservices REST avec Javalin

1. Introduction

Javalin est un framework Web léger écrit pour Java et Kotlin. Il est écrit sur le serveur Web Jetty, ce qui le rend très performant. Javalin est inspiré de koa.js, ce qui signifie qu'il est écrit à partir de zéro pour être simple à comprendre et à développer.

Dans ce didacticiel, nous allons parcourir les étapes de création d'un microservice REST de base à l'aide de ce framework léger.

2. Ajout de dépendances

Pour créer une application de base, nous n'avons besoin que d'une seule dépendance - Javalin lui-même:

 io.javalin javalin 1.6.1 

La version actuelle peut être trouvée ici.

3. Configuration de Javalin

Javalin facilite la configuration d'une application de base. Nous allons commencer par définir notre classe principale et mettre en place une simple application «Hello World».

Créons un nouveau fichier dans notre package de base appelé JavalinApp.java .

Dans ce fichier, nous créons une méthode principale et ajoutons ce qui suit pour configurer une application de base:

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

Nous créons une nouvelle instance de Javalin, la faisons écouter sur le port 7000, puis démarrons l'application.

Nous configurons également notre premier point de terminaison à l'écoute d'une requête GET au point de terminaison / hello .

Lançons cette application et visitons // localhost: 7000 / hello pour voir les résultats.

4. Création d'un UserController

Un exemple «Hello World» est idéal pour introduire un sujet, mais il n'est pas bénéfique pour une vraie application. Examinons maintenant un cas d'utilisation plus réaliste de Javalin.

Tout d'abord, nous devons créer un modèle de l'objet avec lequel nous travaillons. Nous commençons par créer un package appelé user sous le projet racine.

Ensuite, nous ajoutons une nouvelle classe User :

public class User { public final int id; public final String name; // constructors }

En outre, nous devons configurer notre objet d'accès aux données (DAO). Nous utiliserons un objet en mémoire pour stocker nos utilisateurs dans cet exemple.

Nous créons une nouvelle classe dans le pack utilisateur appelé UserDao.java:

class UserDao { private List users = Arrays.asList( new User(0, "Steve Rogers"), new User(1, "Tony Stark"), new User(2, "Carol Danvers") ); private static UserDao userDao = null; private UserDao() { } static UserDao instance() { if (userDao == null) { userDao = new UserDao(); } return userDao; } Optional getUserById(int id) { return users.stream() .filter(u -> u.id == id) .findAny(); } Iterable getAllUsernames() { return users.stream() .map(user -> user.name) .collect(Collectors.toList()); } }

L'implémentation de notre DAO en tant que singleton facilite son utilisation dans l'exemple. Nous pourrions également le déclarer comme membre statique de notre classe principale ou utiliser l'injection de dépendances à partir d'une bibliothèque comme Guice si nous le voulions.

Enfin, nous voulons créer notre classe de contrôleur. Javalin nous permet d'être très flexibles lorsque nous déclarons nos gestionnaires de route, ce n'est donc qu'une façon de les définir.

Nous créons une nouvelle classe appelée UserController.java dans le package utilisateur :

public class UserController { public static Handler fetchAllUsernames = ctx -> { UserDao dao = UserDao.instance(); Iterable allUsers = dao.getAllUsernames(); ctx.json(allUsers); }; public static Handler fetchById = ctx -> { int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id"))); UserDao dao = UserDao.instance(); User user = dao.getUserById(id); if (user == null) { ctx.html("Not Found"); } else { ctx.json(user); } }; }

En déclarant les gestionnaires statiques, nous nous assurons que le contrôleur lui-même ne détient aucun état. Mais, dans les applications plus complexes, nous souhaitons peut-être stocker l'état entre les requêtes, auquel cas nous aurions besoin de supprimer le modificateur statique.

Notez également que les tests unitaires sont plus difficiles avec les méthodes statiques, donc si nous voulons ce niveau de test, nous devrons utiliser des méthodes non statiques.

5. Ajout de routes

Nous avons maintenant plusieurs façons de récupérer les données de notre modèle. La dernière étape consiste à exposer ces données via des points de terminaison REST. Nous devons enregistrer deux nouvelles routes dans notre application principale.

Ajoutons-les à notre classe d'application principale:

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

Après avoir compilé et exécuté l'application, nous pouvons faire une demande à chacun de ces nouveaux points de terminaison. L'appel // localhost: 7000 / users listera tous les utilisateurs et l'appel // localhost: 7000 / users / 0 obtiendra l'objet JSON utilisateur unique avec l'id 0. Nous avons maintenant un microservice qui nous permet de récupérer les données utilisateur .

6. Extension des routes

La récupération des données est une tâche vitale de la plupart des microservices.

Cependant, nous devons également pouvoir stocker des données dans notre banque de données. Javalin fournit l'ensemble complet des gestionnaires de chemin requis pour créer des services.

Nous avons vu un exemple de GET ci-dessus, mais PATCH, POST, DELETE et PUT sont également possibles.

De plus, si nous incluons Jackson en tant que dépendance, nous pouvons analyser automatiquement les corps de requête JSON dans nos classes de modèle. Par exemple:

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

nous permettrait de récupérer l' objet utilisateur JSON du corps de la requête et de le traduire dans l' objet de modèle utilisateur .

7. Conclusion

Nous pouvons combiner toutes ces techniques pour créer notre microservice.

Dans cet article, nous avons vu comment configurer Javalin et créer une application simple. Nous avons également expliqué comment utiliser les différents types de méthodes HTTP pour permettre aux clients d'interagir avec notre service.

Pour des exemples plus avancés d'utilisation de Javalin, assurez-vous de consulter la documentation.

De plus, comme toujours, le code peut être trouvé sur GitHub.