Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 4, 2021 02:20 pm GMT

Elm in the server (or anywhere else) with promises

Elm was created to run on the browser, but every once in a while someone will ask about how to run Elm in a server environment.

At my current job, we needed to sync several clients and persist that shared state somewhere, so we thought it would be a good idea if the server could act like another client that could persist that state in a centralized place.

For that, we created a Node/Express server to run our Elm code and at first, it was very hackish.

In a server-like environment, you mostly always have a request and a response tied together. You ask for something and you might get what you requested or an error. It doesn't matter, for every request, there is a response.

But Elm doesn't work like that if you wanna talk to the outside world. Yes, you can use ports for outside communication, but ports follow the actor model of message passing. So contrary to the request/response nature of server communication, you can only send and receive messages in Elm. That might sound like the same thing but it is not. You can receive a message without ever sending one in the first place. Or send a message without the need to wait for a message back. You can send a message and receive multiple messages back and so on. There is no coupling between sending and receiving a message and that makes Elm kinda unsuitable for a server software where request/response messages are tied.

After looking for better solutions I came across this post in the forums where the user joakin made a clever suggestion: just send the response object from the JavaScript side to a port and send it back through another port when replying to whatever it was requesting. Use the response object to send a proper response to the right client and there you go. You can see an example of that on this helpful repository.

That is something I didn't know: you can pass any JavaScript value as a Json.Decode.Value to Elm, even functions. Of course, you can't do much with them inside Elm but in this case, it helps to tie a specific function call to the message we will send back.

The idea is great and helps us to have some type of tied request/response flow. The problem is when we needed to test the integration. It was easier to bypass all the server stuff and focus on the interoperation between Node and Elm directly. Or even worse, what if the software we were writing wasn't a Node/Express server at all? That is when my boss and co-worker Nate suggested we used promises. Instead of sending the response object from Express to Elm, we could send the resolve function from a promise!

I have made a fork from the example code above with these changes. You can check it out here.

On the Elm side, nothing much has changed. I just made a few naming changes to better reflect the new nature of the interoperation with the JavaScript code. But other than that, we didn't have to change much to make this approach work as both the previous response object that was being sent from Express and the new resolve function from the promise are both just Json.Decode.Values.

The real magic is on the JavaScript code. It is a little bit more complex but it decouples the Elm code and ports from Express itself, making it possible to use that approach virtually anywhere. Here is the bit that makes everything work:

http  .createServer((request, res) => {    new Promise(resolve => app.ports.onRequest.send({ request, resolve }))      .then(({ status, response }) => {        res.statusCode = status;        res.end(response);      });  })  .listen(3000);app.ports.resolve.subscribe(([{ resolve }, status, response]) => {  resolve({ status, response });});
Enter fullscreen mode Exit fullscreen mode

So, it is possible to use Elm in the server, and I would argue that with that approach if you need some kind of tied request/response integration, you can use Elm anywhere where you can use Node. But is it useful? In our case, where we wanted to use most of the code from our client on the server it was a total win, but I would think twice if I wanted to build a full server with Elm as it just doesn't have all the things you will need to make it a good developing experience, although it would be possible.

Maybe Roc will be the language we will use for cases like that. Can't wait for it!

So, what do you think about this approach? Have you done something similar or vastly different to solve the same problem?

Thanks for reading!


Original Link: https://dev.to/eberfreitas/elm-in-the-server-or-anywhere-else-with-promises-5eoj

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To