Une application NodeJS avec Kotlin

Moussa Ndour
5 min readNov 4, 2017

--

Kotlin est un nouveau langage de programmation développée par le célèbre éditeur d’application Jetbrains. C’est un langage moderne et orienté objet qui dispose d’un typage static et inféré et qui permet de compiler son code pour la JVM ou vers du Javascript.

Kotlin présente une syntaxe moderne proche de celle de Swift, qui réduit drastiquement la quantité de code nécessaire a l’écriture d’une application.

Prenons la class Java suivante

public class User {
private String firstName;

private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}

Le code équivalent en Kotlin:

class User {
var firstName: String? = null
var lastName: String? = null
}

Projet de Test

Nous allons écrire un petit serveur en Kotlin qui se limitera à renvoyer un profile utilisateur aléatoire a chaque requête.

Démarer Le projet avec IntelliIDEA

Cliquer sur File -> New Project , puis sélectionner Kotlin dans le panel de gauche, puis cliquer sur Kotlin/JS.

Puis cliquer sur Next.

Ensuite entrer le nom du projet puis indiquer le chemin du SDK Java a l’IDE si vous ne l’avez pas encore configuré puis cliquer sur Finish.

Une fois le nouveau projet ouvert, exécuter nous allons initialiser un projet Node:

npm init

Un fichier package.json a été ajouté au projet, ouvrez là et ajouter ceci a la section scripts:

"start": "node out/production/TestProject/TestProject.js"// chemin vers lequelle sera generer le code javascript

Installer aussi ses 3 modules que nous utiliserons par la suite dans le projet:

yarn add express node-fetch request

Le contenu du fichier package.json doit maintenant ressembler a ceci:

{
"name": "testproject",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node out/production/TestProject/TestProject.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.16.2",
"node-fetch": "^1.7.3",
"request": "^2.83.0"
}
}

Ensuite il faut signaler au compilateur Kotlin que nous allons utiliser les systèmes de module de NodeJS, pour cela cliquer Préférences(MAC) ou Settings -> Build, Execution, Deployment -> Kotlin Compiler puis choisisser CommonsJs.

Ensuite remplissez le champs Destination Directory par node_modules puis cliquer sur OK. Vous pouvez aussi générer les sources map pour débuger votre code avec les extension de Jetbrains.

Le Serveur

Ajouter un fichier server.kt dans le dossier src.

Puis coller y la code suivant:

fun main(args: Array<String>) { 
// Point d'entree
}

La fonction main et le point d’entrée de notre application.

Importer les modules

Étant un langage typé statique, Kotlin doit encore interagir avec des environnements non typés ou mal typés, tels que l’écosystème JavaScript. Pour faciliter ces cas d’utilisation, le type dynamic est disponible dans la langue:

val dyn: dynamic = ...

Pour indiquer à Kotlin qu’une certaine déclaration est écrite en JavaScript pur, vous devez la marquer avec un modificateur extern. Lorsque le compilateur voit une telle déclaration, il suppose que l’implémentation pour la class, la fonction ou la propriété correspondante est fournie par le développeur et n’essaie donc pas de générer du code JavaScript à partir de la déclaration. Cela signifie que vous devez omettre les corps des déclarations externes.

Nous allons utiliser ceci pour indiquer a Kotlin la fonction require qui permet de charger les modules en ajoutant ceci en haut de notre fichier:

external fun require(module:String):dynamic 
fun main(args: Array<String>) {
}

Maintenant nous pouvons inclure tous nos modules sans avoir une erreur à la compilation:

external fun require(module:String):dynamicfun main(args: Array<String>) {    val express = require("express")
val app = express()
val request = require("request")


}

Ensuite ajoutons nos routes:

import kotlin.js.jsonexternal fun require(module:String):dynamicfun main(args: Array<String>) {
println("Hello Word!")
val express = require("express")
val app = express()
val request = require("request")
app.get("/", { _, res: dynamic -> request("https://randomuser.me/api/", {_, _, body ->
if(body != null){
res.json( json(
"success" to 1,
"user" to JSON.parse(body),
"others" to arrayOf<String>(
"Kotin",
"Javascript",
"Intercal",
"Malbodge",
"BrainFuck"
)
));
}
else{
res.json( json(
"success" to -1
));
}
}) })

app.listen(5000, {
println("Listening on port 5000")
})
}

Cliquer sur Build -> Build Project pour générer les fichier JS ensuite exécuter:

npm start # ou node out/production/TestNodeJs/TestNodeJs.js

Maintenant si vous ouvres votre navigateur et que vous allez vers l’url vous aurait un résultat similaire a ceci:

Utiliser les Promises

Kotlin expose une API qui permet d’utiliser les principaux Object Javascript. Nous allons utiliser ceci pour crée une autre route qui fait la même chose que la précédent mais qui utilise les promesses:

import kotlin.js.Promiseapp.get("/with-promise", { _, res ->    val fetch = require("node-fetch") !!as (url: String) -> Promise<dynamic>    fetch("https://randomuser.me/api/")
.then({result -> result.json() !!as Any})
.then({jsonResult: Any ->
res.json( json(
"success" to 1,
"user" to jsonResult,
"others" to arrayOf<String>(
"Kotin",
"Javascript",
"Intercal",
"Malbodge",
"BrainFuck"
)
)) as? Unit
})
.catch { _ ->
res.json( json(
"success" to -1
)) as? Unit
}
})

Vous remarquerais que j’ai typé certaines variable pour ignorer les warning de l’IDE.

Le code ou complet du serveur sera alors:

import kotlin.js.Promise
import kotlin.js.json
external fun require(module:String):dynamicfun main(args: Array<String>) {
println("Hello Word!")
val express = require("express")
val app = express()
val request = require("request")
app.get("/", { _, res: dynamic -> request("https://randomuser.me/api/", {_, _, body ->
if(body != null){
res.json( json(
"success" to 1,
"user" to JSON.parse(body),
"others" to arrayOf<String>(
"Kotin",
"Javascript",
"Intercal",
"Malbodge",
"BrainFuck"
)
));
}
else{
res.json( json(
"success" to -1
));
}
}) })app.get("/with-promise", { _, res -> val fetch = require("node-fetch") !!as (url: String) -> Promise<dynamic> fetch("https://randomuser.me/api/")
.then({result -> result.json() !!as Any})
.then({jsonResult: Any ->
res.json( json(
"success" to 1,
"user" to jsonResult,
"others" to arrayOf<String>(
"Kotin",
"Javascript",
"Intercal",
"Malbodge",
"BrainFuck"
)
)) as? Unit
})
.catch { _ ->
res.json( json(
"success" to -1
)) as? Unit
}
})
app.listen(5000, {
println("Listening on port 5000")
})
}

Le code complet du projet est disponible sur Github à cette adresse.

--

--