Creating simple node server with Kotlin


#1

I’m trying to create simple node server, using kotlin lang, that is replicating the basic sample here:

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

So, I did the below:

Created new folder, named it node

Created new gradle project using this command: gradle init --type java-library

Deleted the src/main and the src/test folders

Created the src/kotlin and src/resources folders

Replaced the content of the build.gradle file by:

buildscript {
    ext.kotlin_version = '1.2.21'
    ext.node_dir = 'node'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 
    }
}
apply plugin: 'kotlin2js'

repositories {     jcenter()    }

dependencies {
    def kotlinx_html_version = "0.6.8"
    compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}

sourceSets.main {
   kotlin.srcDirs += 'src/kotlin'
   resources.srcDirs += 'src/resources'
}

compileKotlin2Js.kotlinOptions {
   outputFile = "${projectDir}/${node_dir}/index.js"
   moduleKind = "commonjs" 
   sourceMap = true
}

clean.doFirst() {
    delete("${node_dir}")
}

Installed kotlin from npm as local version: npm i kotlin
Note: installing it globally npm i -g kotlin did not work at all.

Created my file at src/kotlin/Main.Kt as below:

external fun require(module:String):dynamic

fun main(args: Array<String>) {
    println("Hello JavaScript!")

    val http = require("http")
    val hostname = "127.0.0.1"
    val port = 3000

    println("Server will try to run at http://${hostname}:${port}/")

    val server = http.createServer{req, res -> 
        res.statusCode = 200
        res.setHeader("Content-Type", "text/plain")
        res.end("Hello World\n")
    }

    server.listen{port, hostname ->
       println("Server running at http://${hostname}:${port}/")
    }
}

Built the project using gradle build and got the index.js file generated as required.

Once running the file node index.js it did not work, and looks the app not reading the values of port and host upon calling the server.listen.

The structure, code and output of the app are in this screenshot:

enter image description here

The index.js generated is:

(function (_, Kotlin) {
  'use strict';
  var println = Kotlin.kotlin.io.println_s8jyv4$;
  var Unit = Kotlin.kotlin.Unit;
  function main$lambda(req, res) {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    return res.end('Hello World\n');
  }
  function main$lambda_0(port, hostname) {
    println('Server running at http://' + hostname + ':' + port + '/');
    return Unit;
  }
  function main(args) {
    println('Hello JavaScript!');
    var http = require('http');
    var hostname = '127.0.0.1';
    var port = 3000;
    println('Server will try to run at http://127.0.0.1:3000/');
    var server = http.createServer(main$lambda);
    server.listen(main$lambda_0);
  }
  _.main_kand9s$ = main;
  main([]);
  Kotlin.defineModule('index', _);
  return _;
}(module.exports, require('kotlin')));

//# sourceMappingURL=index.js.map

Equivalent Kotlin code to my JavaScript code
#2

Just found it, the correct code worked with me is:

server.listen(port, hostname, fun() { 
    println("Server running at http://${hostname}:${port}/")
})

#3

I think you can use a lambda expression.

server.listen(port, hostname, () ->
    println("Server running at http://${hostname}:${port}/"))

Can you try it?


#4

Your syntax for lambda expressions is wrong. I think you used the Java syntax(I don’t use Java much so I’m not sure). The Kotlin version would be

server.listen(port, hostname, {
    println("Server running at http://${hostname}:${port}/") } )

If the lambda is the last argument you can also write

server.listen(port, hostname) {
    println("Server running at http://${hostname}:${port}/") }

This version would be the idomatic way of writing this.

That said, there are some advantages to using anonymous functions as @hasan.oryx did. You can use return in them for example. Even though I would use a lambda expression in this case.


#5

This way did not work with me, thanks for the feedback.


#6

Thanks, but looks you have extra ) at the end of this:


#7

Yup, your right. Changing it right now :wink: