Introduction à Micronaut Framework

1. Qu'est-ce que Micronaut

Micronaut est un framework basé sur JVM pour la création d'applications légères et modulaires. Développé par OCI, la même société qui a créé Grails, Micronaut est le dernier framework conçu pour rendre la création de microservices rapide et facile .

Bien que Micronaut contienne des fonctionnalités similaires aux frameworks existants tels que Spring, il possède également de nouvelles fonctionnalités qui le distinguent. Et avec la prise en charge de Java, Groovy et Kotlin, il offre une variété de façons de créer des applications.

2. Caractéristiques principales

L'une des fonctionnalités les plus intéressantes de Micronaut est son mécanisme d'injection de dépendance au temps de compilation. La plupart des frameworks utilisent la réflexion et les proxies pour effectuer l'injection de dépendances au moment de l'exécution. Micronaut, cependant, construit ses données d'injection de dépendances au moment de la compilation. Le résultat est un démarrage plus rapide de l'application et une empreinte mémoire réduite.

Une autre caractéristique est son support de première classe pour la programmation réactive, à la fois pour les clients et les serveurs. Le choix d'une implémentation réactive spécifique est laissé au développeur car RxJava et Project Reactor sont pris en charge.

Micronaut possède également plusieurs fonctionnalités qui en font un excellent cadre pour le développement d'applications cloud natives. Il prend en charge plusieurs outils de découverte de services tels qu'Eureka et Consul, et fonctionne également avec différents systèmes de traçage distribués tels que Zipkin et Jaeger.

Il prend également en charge la création de fonctions AWS lambda, ce qui facilite la création d'applications sans serveur.

3. Premiers pas

Le moyen le plus simple de commencer consiste à utiliser SDKMAN:

> sdk install micronaut 1.0.0.RC2

Cela installe tous les fichiers binaires dont nous aurons besoin pour créer, tester et déployer les applications Micronaut. Il fournit également l'outil CLI Micronaut, qui nous permet de démarrer facilement de nouveaux projets.

Les artefacts binaires sont également disponibles sur Sonatype et GitHub.

Dans les sections suivantes, nous examinerons certaines fonctionnalités du framework.

4. Injection de dépendance

Comme mentionné précédemment, Micronaut gère l'injection de dépendances au moment de la compilation, ce qui est différent de la plupart des conteneurs IoC.

Cependant, il prend toujours pleinement en charge les annotations JSR-330, de sorte que le travail avec des beans est similaire à d'autres frameworks IoC.

Pour transférer automatiquement un bean dans notre code, nous utilisons @Inject:

@Inject private EmployeeService service;

L' annotation @Inject fonctionne exactement comme @Autowired et peut être utilisée sur les champs, les méthodes, les constructeurs et les paramètres.

Par défaut, tous les beans sont considérés comme un prototype. Nous pouvons rapidement créer des beans singleton en utilisant @Singleton. Si plusieurs classes implémentent la même interface de bean, @Primary peut être utilisé pour les déconfliger:

@Primary @Singleton public class BlueCar implements Car {}

L' annotation @Requires peut être utilisée lorsque les beans sont facultatifs, ou pour effectuer le câblage automatique uniquement lorsque certaines conditions sont remplies.

À cet égard, il se comporte un peu comme les annotations Spring Boot @Conditional :

@Singleton @Requires(beans = DataSource.class) @Requires(property = "enabled") @Requires(missingBeans = EmployeeService) @Requires(sdk = Sdk.JAVA, value = "1.8") public class JdbcEmployeeService implements EmployeeService {}

5. Construire un serveur HTTP

Regardons maintenant la création d'une application serveur HTTP simple. Pour commencer, nous utiliserons SDKMAN pour créer un projet:

> mn create-app hello-world-server -build maven

Cela créera un nouveau projet Java en utilisant Maven dans un répertoire nommé hello-world-server. Dans ce répertoire, nous trouverons le code source de notre application principale, le fichier Maven POM et d'autres fichiers de support pour le projet.

L'application par défaut qui est très simple:

public class ServerApplication { public static void main(String[] args) { Micronaut.run(ServerApplication.class); } }

5.1. Bloquer HTTP

À elle seule, cette application ne fera pas grand-chose. Ajoutons un contrôleur qui a deux points de terminaison. Les deux renverront un message d'accueil, mais l'un utilisera le verbe HTTP GET , et l'autre utilisera POST:

@Controller("/greet") public class GreetController { @Inject private GreetingService greetingService; @Get("/{name}") public String greet(String name) { return greetingService.getGreeting() + name; } @Post(value = "/{name}", consumes = MediaType.TEXT_PLAIN) public String setGreeting(@Body String name) { return greetingService.getGreeting() + name; } }

5.2. E / S réactives

Par défaut, Micronaut implémentera ces terminaux en utilisant les E / S bloquantes traditionnelles. Cependant, nous pouvons rapidement implémenter des points de terminaison non bloquants en changeant simplement le type de retour en n'importe quel type réactif non bloquant .

Par exemple, avec RxJava, nous pouvons utiliser Observable . De même, lors de l'utilisation de Reactor, nous pouvons renvoyer des types de données Mono ou Flux :

@Get("/{name}") public Mono greet(String name) { return Mono.just(greetingService.getGreeting() + name); }

Pour les points de terminaison bloquants et non bloquants, Netty est le serveur sous-jacent utilisé pour gérer les requêtes HTTP.

Normalement, les demandes sont gérées sur le pool de threads d'E / S principal qui est créé au démarrage, ce qui les bloque.

Cependant, lorsqu'un type de données non bloquant est retourné à partir d'un point de terminaison de contrôleur, Micronaut utilise le thread de boucle d'événement Netty, rendant l'ensemble de la requête non bloquant.

6. Création d'un client HTTP

Créons maintenant un client pour consommer les points de terminaison que nous venons de créer. Micronaut propose deux façons de créer des clients HTTP:

  • Un client HTTP déclaratif
  • Un client HTTP programmatique

6.1 Client HTTP déclaratif

Le premier et le plus rapide moyen de créer consiste à utiliser une approche déclarative:

@Client("/greet") public interface GreetingClient { @Get("/{name}") String greet(String name); }

Remarquez que nous n'implémentons aucun code pour appeler notre service . Au lieu de cela, Micronaut comprend comment appeler le service à partir de la signature de méthode et des annotations que nous avons fournies.

To test this client, we can create a JUnit test that uses the embedded server API to run an embedded instance of our server:

public class GreetingClientTest { private EmbeddedServer server; private GreetingClient client; @Before public void setup() { server = ApplicationContext.run(EmbeddedServer.class); client = server.getApplicationContext().getBean(GreetingClient.class); } @After public void cleanup() { server.stop(); } @Test public void testGreeting() { assertEquals(client.greet("Mike"), "Hello Mike"); } }

6.2. Programmatic HTTP Client

We also have the option of writing a more traditional client if we need more control over its behavior and implementation:

@Singleton public class ConcreteGreetingClient { private RxHttpClient httpClient; public ConcreteGreetingClient(@Client("/") RxHttpClient httpClient) { this.httpClient = httpClient; } public String greet(String name) { HttpRequest req = HttpRequest.GET("/greet/" + name); return httpClient.retrieve(req).blockingFirst(); } public Single greetAsync(String name) { HttpRequest req = HttpRequest.GET("/async/greet/" + name); return httpClient.retrieve(req).first("An error as occurred"); } }

The default HTTP client uses RxJava, so can easily work with blocking or non-blocking calls.

7. Micronaut CLI

We've already seen the Micronaut CLI tool in action above when we used it to create our sample project.

In our case, we created a standalone application, but it has several other capabilities as well.

7.1. Federation Projects

In Micronaut, a federation is just a group of standalone applications that live under the same directory. By using federations, we can easily manage them together and ensure they get the same defaults and settings.

When we use the CLI tool to generate a federation, it takes all the same arguments as the create-app command. It will create a top-level project structure, and each standalone app will be created in its sub-directory from there.

7.2. Features

When creating a standalone application or federation, we can decide which features our app needs. This helps ensure the minimal set of dependencies is included in the project.

We specify features using the -features argument and supplying a comma-separated list of feature names.

We can find a list of available features by running the following command:

> mn profile-info service Provided Features: -------------------- * annotation-api - Adds Java annotation API * config-consul - Adds support for Distributed Configuration with Consul * discovery-consul - Adds support for Service Discovery with Consul * discovery-eureka - Adds support for Service Discovery with Eureka * groovy - Creates a Groovy application [...] More features available

7.3. Existing Projects

We can also use the CLI tool to modify existing projects. Enabling us to create beans, clients, controllers, and more. When we run the mn command from inside an existing project, we'll have a new set of commands available:

> mn help | Command Name Command Description ----------------------------------------------- create-bean Creates a singleton bean create-client Creates a client interface create-controller Creates a controller and associated test create-job Creates a job with scheduled method

8. Conclusion

In this brief introduction to Micronaut, we've seen how easy it is to build both blocking and non-blocking HTTP servers and clients. Also, we explored some features of its CLI.

But this is just a small taste of the features it offers. There is also full support for serverless functions, service discovery, distributed tracing, monitoring and metrics, a distributed configuration, and much more.

And while many of its features are derived from existing frameworks such as Grails and Spring, it also has plenty of unique features that help it stand out on its own.

Comme toujours, nous pouvons trouver les exemples de code ci-dessus dans notre dépôt GitHub.