Home

Awesome

Servant-Elm Example App

This is an example application making use of the servant-elm library.

To build and run this application, you need to install stack and Elm.

Assuming you have both tools installed, you can run the example with:

make && make serve

App layout

If you study servant-elm-example-app.cabal, you will see that the Haskell part of this project comprises four build targets:

  1. an api library, which will contain our Servant API type and server implementation;

  2. a backend executable, which serves a home page and our API under /api, as well as our static assets;

  3. a code-generator executable, which uses servant-elm to generate Elm code for interacting with our API; and

  4. a test-suite (not yet implemented).

Our Elm code is in the frontend/src directory.

Build process

The Makefile ties everything together.

First we build the api library and the backend and code-generator executables by running stack build.

Then we run stack exec code-generator, directing the output Elm code to frontend/src/Generated/Api.elm.

Finally, we run elm-make to build frontend/dist/app.js.

Components in detail

The API

The definition of our API lives in api/Api/Types.hs. It's pretty simple. You can:

The first returns a JSON representation of a book, and the second returns a list of such representations.

The implementation lives in api/Api/Server.hs. The book database state lives in a TVar BookDB, which must be supplied by the user.

The backend

backend/Main.hs defines a type called SiteApi, which wraps our book API under /api, provides an index route and serves assets under /assets.

The server function implements this SiteApi. It wraps the API server implementation, serves the frontend/dist directory as /assets, and serves a home page.

The home page simply sets a page title and bootstraps our Elm app (which will be built to frontend/dist/app.js).

The main function creates a new TVar for our book database API and starts the app on port 8000.

The code generator

code-generator/Main.hs imports our Api type and calls servant-elm's elmJSWith with some options:

The frontend

In frontend/src/Main.elm we import the Generated.Api module. Our Elm app uses the Html module (see The Elm Architecture for details).

The functions fetchBooks and the use of postBooks in update demonstrate how the generated Elm functions can be used. The generated functions getBooks and postBooks have types Http.Request (List (Book)) and Book -> Http.Request (Book) respectively. The Http.Request a type is passed to the Http.send function to actually perform the requests.

TODO