約束のあるサーバー(または他のどこか)のエルム


ELMはブラウザ上で動作するように作成されましたが、サーバー環境でELMを実行する方法については、時々誰かが尋ねます.
私の現在の仕事で、我々はいくつかのクライアントを同期させて、共有状態をどこかで固守する必要があったので、サーバーが集中した場所でその状態を持続させることができたもう一つのクライアントのように行動することができるならば、それが良い考えであると思いました.
そのために、ELMコードを実行するためのノード/エクスプレスサーバを作成しました.
サーバーのような環境では、ほとんどの場合、常に要求と応答を結び付けている.あなたは何かを求め、あなたが要求したものやエラーを得るかもしれません.それは問題ではない、すべての要求については、応答があります.
しかし、エルムは、あなたが外の世界と話したいならば、そのように働きません.はい、使用できますports 外部通信のために、しかし、ポートはメッセージパッシングの俳優モデルに続きます.サーバ通信のリクエスト/レスポンスの性質に反して、ELMでメッセージを送受信することができます.それは同じことのように聞こえるかもしれませんが、そうではありません.あなたが最初の場所で1つを送信せずにメッセージを受け取ることができます.またはメッセージを待つ必要がないメッセージを送信します.あなたがメッセージを送信することができますし、戻って、複数のメッセージを受信します.メッセージを送ることと受信することの間には結合がありません、そして、要求/応答メッセージが結びつくサーバー・ソフトウェアに、ELM Kindaが不適当にします.
より良い解決策を探した後this post ユーザーがいるフォーラムでjoakin 巧妙な提案をしました:ちょうどJavaScript側から応答オブジェクトをポートに送って、それが要求していたものに返信するとき、別のポートを通してそれを送り返してください.応答オブジェクトを使用して適切なクライアントに適切な応答を送信します.あなたはその例を見ることができますon this helpful repository .
それは私が知らなかった何かです:あなたは、どんなJavaScript価値でも Json.Decode.Value elm,even関数に.もちろん、elmの内部ではあまり使えませんが、この場合、送信するメッセージに特定の関数呼び出しを結び付けるのに役立ちます.
アイデアは素晴らしいですし、私たちは結合の要求/応答の流れのいくつかのタイプを持つことができます.問題は、我々が統合をテストする必要があるときです.すべてのサーバのものを迂回して、ノードとelmの間の直接操作に集中するのは簡単でした.またはさらに悪いことに、我々が書いていたソフトウェアがすべてのノード/Expressのサーバーではなかったか?それは私の上司と同僚が約束を使用して提案したときです.ElmからElmまで応答オブジェクトを送る代わりに、我々は約束から解決機能を送ることができました!
私は上記の例のコードからフォークを作りました.あなたはそれをチェックアウトすることができますhere .
Elm side , 何も変わりませんでした.JavaScriptコードとの相互運用の新しい性質をより良く反映するために、いくつかの命名の変更をしました.しかし、それ以外にも、このアプローチは、Expressから送信されていた前の応答オブジェクトと、その約束からの新しい解決機能の両方が、どちらもJson.Decode.Value s.
本当の魔法はJavaScript code . それは少しより複雑です、しかし、それは表現自体からelmコードとポートを切り離します.ここではすべてが動作するビットです.
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 });
});
それで、サーバーでELMを使用することが可能です、そして、私は、あなたが何らかの種類の縛られた要求/応答統合を必要とするならば、あなたがノードを使うことができるところで、あなたがどこでELMを使うことができるかについて、そのアプローチでそれを主張します.でも役に立つ?私たちのケースでは、サーバー上のクライアントからのコードのほとんどを使用したい場合、それは合計勝利だったが、私はエルムと完全なサーバーを構築したい場合は、それはちょうどそれが可能であるが、それは良い開発経験をする必要があるすべてのものを持っていないように私は2回考えるだろう.
Maybe Roc 私たちがそのような場合に使用する言語になります.それを待つことはできません!
では、このアプローチについてどう思いますか?何か同じようにまたは大幅に同じ問題を解決するために異なるか?
読書ありがとう!