Une application NodeJS avec Kotlin
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.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.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.