eberfreitas / elm-express / Express

elm-express is an Elm library that provides a lightweight and expressive API for building server-side applications on top of the popular Node.js web framework, Express. With elm-express, developers can leverage the safety and expressiveness of Elm for building web backends in a familiar and powerful environment.

How it works?

When an incoming request arrives, Express sends the request data through a port called requestPort to the Elm application, which can then define a response and route it through another port called responsePort.

To simplify the integration between the Express server and the Elm application, elm-express comes with a JavaScript library that takes care of most of the wiring. The README contains documentation on how to use the library, and the /example folder in the repository provides a practical demonstration of how to wire everything up.

Creating an elm-express application

application : App flags ctx msg model -> Platform.Program flags (Model model ctx) (Msg msg)

This function wraps the Platform.worker function to create a "headless" Elm application that should be instantiated by a Node.js script.

For a more in-depth understanding of how to use this library and create your own application, take a look at the app in the /example folder in the repository/source.

Types


type alias AppInit flags ctx =
flags -> ctx

The AppInit type alias represents the init function that runs when the application is started. It is similar to the init function of Platform.worker, and provides an opportunity to pass in "context" data that can be used throughout the application.

This is an ideal place to provide any data that will not change during the application's lifecycle, such as environment variables. By passing such data as context, you can ensure that it is available to all parts of the application that need it.


type alias AppIncoming ctx msg model =
ctx -> Request -> Response -> ( Conn model
, Platform.Cmd.Cmd msg 
}

Describes the incoming function that gets called whenever a new request happens.


type alias AppUpdate msg model ctx =
ctx -> msg -> Conn model -> ( Conn model
, Platform.Cmd.Cmd msg 
}

The AppUpdate type alias represents the update function of your Elm application. This function is responsible for processing messages that are typically tied to port or task interactions.

The update function takes three arguments: a context (ctx), a message (msg), and a connection (Conn.Conn model) that represents the current state of the application. Based on these inputs, the function returns a tuple containing a new connection (Conn.Conn model) and any commands (Cmd msg) that should be executed as a result of the message processing.


type alias AppDecodeRequestId msg =
msg -> Result Json.Decode.Error String

The AppDecodeRequestId type alias represents the decodeRequestId function, which is called whenever a subscription message is received. This function extracts the request ID from the message value in order to select the connection associated with the request.


type alias App flags ctx msg model =
{ requestPort : (Json.Decode.Value -> Msg msg) -> Platform.Sub.Sub (Msg msg)
, responsePort : Json.Encode.Value -> Platform.Cmd.Cmd (Msg msg)
, errorPort : String -> Platform.Cmd.Cmd (Msg msg)
, poolPort : (String -> Msg msg) -> Platform.Sub.Sub (Msg msg)
, init : AppInit flags ctx
, incoming : AppIncoming ctx msg model
, decodeRequestId : AppDecodeRequestId msg
, update : AppUpdate msg model ctx
, subscriptions : Platform.Sub.Sub msg
, middlewares : List (Middleware ctx msg) 
}

The App type alias represents all the parameters that need to be set up for your Elm application to work with elm-express. In addition to well-known functions like init and update, you need to provide four different ports that will be used for wiring:

You can also provide a list of middlewares to run at every request. Please refer to the Express.Middleware documentation to learn how to use middleware.

For a full example of how to instantiate a new App value, see the /example folder in the repository/source.

Internal types


type alias Pool model =
Dict String (Conn model)

Internal connections pool.


type alias Model model ctx =
{ pool : Pool model
, context : ctx 
}

Internal model.


type Msg msg

Internal messages.