I have created a lot of Express servers and a lot of my projects starts that way. Recently I have gotten into ReasonML and naturally I wanted to create my first express.js server and see how difficult that would be.

A pretty normal express.js server in Node.js looks like this:

const express = require('express')

let app = express()

app.get('/', (req, res) => {

res.send('Hi')

})

app.listen(9000)

First I created it like this, which worked but did not look correct!



type res = {.

[

};

type handler = (string, res) => string;

type express = {.

[

[

};

[ type listen = int => int;type res = {. @bs .meth] "send": string => string};type handler = (string, res) => string;type express = {. @bs .meth] "listen": int => int, @bs .meth] "get": (string, handler) => string}; @bs .module] external express : unit => express = "express"; let app = express(); app##get("/", (_, res) => {

res##send("hi")

}); app##listen(9000)

This was after a lot of trial and error but the output was correct! Success at first glance, then we can always improve!

// Generated by BUCKLESCRIPT VERSION 2.2.3, PLEASE EDIT WITH CARE

'use strict'; var Express = require("express"); var app = Express(); app.get("/", (function (_, res) {

return res.send("hi");

})); app.listen(9000); exports.app = app;

/* app Not a pure module */

But the way we are running functions directly on objects is not and does not look correct. After some help and hints on the ReasonML Discord I made it look like this:



type response;

type handler = (string, response) => unit;

[

[

[

[ type express;type response;type handler = (string, response) => unit; @bs .send] external get : (express, string, handler) => unit = ""; @bs .send] external send : (response, string) => unit = ""; @bs .send] external listen : (express, int) => unit = ""; @bs .module] external express : unit => express = "express"; let app = express();

get(app, "/", (_, res) => {

send(res, "hi");

}); listen(app, 9000)

Which still produces the same output:

// Generated by BUCKLESCRIPT VERSION 2.2.3, PLEASE EDIT WITH CARE

'use strict'; var Express = require("express"); var app = Express(); app.get("/", (function (_, res) {

res.send("hi");

return /* () */0;

})); app.listen(9000); exports.app = app;

/* app Not a pure module */

You can see that we are calling functions with express and response object as arguments, much cleaner but still not immutable but that can be for another topic!

This is not a full example of typing the whole express.js api, but it gives you a quick glance of how you can do it yourself.

What do you like about ReasonML and what are you learning about it?