Le module API

C'est parti, vous allez à présent porter votre premier module en Kotlin : api.

Maven

Ajoutez au pom du module api les dépendances précédemment ajoutées dans le POM parent.

<project>
    <dependencies>
        ...
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
        </dependency>
    </dependencies>
</project>

et ajoutez également le plugin précédemment configuré dans le pom parent

<build>
    <plugins>
        ...
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
        </plugin>
    </plugins>
</build>

ApiApplication

Attention

N'hésitez pas à commenter vos tests s'ils ne passent pas le temps de la migration vers Kotlin.

Commencez par le plus petit fichier : renommer le fichier ApiApplication.java en ApiApplication.kt.

Changer la syntaxe de class Java en class Kotlin :

@OneAnnotation
class MyClass()

TIP

Pensez à supprimer tout ce qui est inutile comme les point-virgules, les constructeurs vides et les block vides.

TIP

En Kotlin, le main n'est pas à mettre dans une classe.

Changer la méthode main pour utiliser spring boot :

import org.springframework.boot.runApplication

fun main(args: Array<String>) {
    runApplication<ApiApplication>(*args)
}

Kotlin compilant en class, l'interoparabilité avec Java est complète. Vérifier que votre application démarre.

Controller

Au tour du package controller, renommer le fichier PokemonsController.java en PokemonsController.kt.

Réécriver ce fichier en kotlin. Ce fichier ne doit pas contenir de block de fonction, uniquement des fonctions Single-Expression, let et l'opérateur elvis.

Single-Expression functions

En kotlin il est courant d'avoir des fonctions sans body. Par exemple :

fun provideSomething(): Something {
  return Toto.makeIt()
}

Va plutôt s'écrire en une seule ligne

fun provideSomething() = Toto.makeIt()

let et elvis

Les scoping function (let, also, apply, etc.), et l'opérateur elvis sont souvent utilisés conjointement pour gérer les valeurs nullable.

Scope functions

valeurNullable?.let { /*code exécuté si valeurNullable n'EST PAS nulle*/ }

Elvis

valeurNullable ?; "valeur de remplacement en cas de null"

Bonus

💡 Utiliser une extension wrap pour retourner ResponseEntity.ok(it) si le service vous retourne un objet et ResponseEntity.notFound().build() sinon.

Après avoir vérifié que votre serveur redémarre toujours, et que vos pokemons s'affrontent bien, convertissez le fichier ForwardController en kotlin.

Repository & Client

Réécrire les fichiers PokemonRepository et ArenaApi en Kotlin en utilisant une interface Kotlin.

List

En Kotlin, on préfère l'immutabilité. java.util.List n'étant pas immutable, préférez l'utlisation de kotlin.collections.List (immutable) ou alors kotlin.collections.MutableList (mutable)

Configuration

Réécrire le fichier ApiClientConfiguration en kotlin avec les contraintes suivantes :

  • Pas de block de fonction, uniquement des fonctions Single-Expression
  • Utiliser la référence de classe Java à partir de la Kclass de AreneApi

Entités

Réécrire le fichier BattleEntity en tant que data class Kotlin. Pour le fichier Pokemon utiliser une classe Kotlin qui aura :

  • un constructeur par défaut non vide
  • la fonction toPokemon qui utilisera la fonction apply fournie par Kotlin

Service

Pour finir avec ce module, il nous reste à porter PokemonService.

Pour cela :

  • Injecter l'ensemble des dépendances dans le constructeur par défaut
  • Réécrire la fonction getAllPokemon en fonction Single-Expression
  • Réécrire la fonction getPokemonByIdOrName en fonction Single-Expression à l'aide d'un opérateur elvis
  • Réécrire la fonction getAllPokemonTypes en fonction Single-Expression
  • Réécrire la fonction fight
  • Réécrire la fonction getBattle en fonction Single-Expression

Vérification

Vérifier que l'ensemble de l'API fonctionne en lançant un combat depuis http://localhost:8080.