Work in Progress: rescript-express

Hi! I’m working on (nearly) zero-cost bindings for express (some APIs require a tiny layer as they return whether a bool or a string :persevere:).

I’ve added the main APIs. If you use express and want to provide some feedback about things that look weird or missing APIs, don’t hesitate.

Looks like the following:

open Express

let app = express()

app->use(jsonMiddleware())

app->get("/", (_req, res) => {
  open Res
  let _ = res->status(200)->json({"ok": true})
})

app->post("/ping", (req, res) => {
  open Req
  let name = (req->body)["name"]
  open Res
  let _ = res->status(200)->json({"message": `Hello ${name}`})
})

let _ = app->listen(8081)
9 Likes

Kinda related: did you have a look at fastifyjs yet? it seems to be a better supported, more stable http server framework than express. It’s also maintained by one of Node’s core maintainers

I’d probably not use express for any new projects anymore

7 Likes

did you have a look at fastifyjs yet

Nope, I use express out of habit I guess. I’ll have a look

I’ve also never used fastifyjs, looks interesting!

Also have a look at bs-express. The master branch has been ported to Rescript syntax. If it’s similar enough to what you’re planning, the project is actively looking for a maintainer if you are interested. :slight_smile:

uff, we need to get rid / migrate all the old libraries that start with ˋbs-ˋ… so many old artifacts that are not idiomatic to ReScript anymore and need a total rewrite. The new convention is ˋrescript-[mylib]ˋ, like @bloodyowl did.

Very hard to tell which libraries are actually being actively maintained, and which ones are just old artifacts of our previous ecosystem.

2 Likes

I thought about that, but the API I wanted is so far away from the original one that it’d make all the bs-express users unhappy with the changes if they upgrade to a new one that has nothing to do with the original.

1 Like

I use express a bit (I don’t like it much). Seems like error handlers are not supported yet:

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

If they’re abandoned, wouldn’t they only have a bucklescript tag and not a rescript tag? that might be a good way to filter them.

Hey @bloodyowl , can we have more examples for rescript-express, please?
I am trying to use the request query parameters and I got stuck here:

let app = express()
app->get("/params", (req, res) => {
  let key = req->query["key"]
  Js.log(key)
})

The compiler reports back saying:

This expression has type Express.req => 'a
It has no method key

Should I be pattern matching here instead?

I think this is a syntax issue. Try (req->query)["key"], or just query(req)["key"].

1 Like

Nice catch, thanks! I modified my code to keep it readable:

let app = express()
app->get("/params", (req, res) => {
  let reqParams = req->query
  let key = reqParams["key"]
  Js.log(key)
})

Hi Sprkv
From your example it looks like the app object is exposed mutably?

Thanks
Alex