# Servant Elm [![Build Status](https://travis-ci.org/mattjbray/servant-elm.svg?branch=master)](https://travis-ci.org/mattjbray/servant-elm) Generate Elm functions to query your Servant API! Elm type generation coutesy of [krisajenkins/elm-export](https://github.com/krisajenkins/elm-export). ## Installation Servant Elm is [available on Hackage](http://hackage.haskell.org/package/servant-elm). ## Example First, some language pragmas and imports. ```haskell {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} import Elm (Spec (Spec), specsToDir, toElmDecoderSource, toElmTypeSource) import GHC.Generics (Generic) import Servant.API ((:>), Capture, Get, JSON) import Servant.Elm (ElmType, Proxy (Proxy), defElmImports, generateElmForAPI) ``` We have some Haskell-defined types and our Servant API. ```haskell data Book = Book { name :: String } deriving (Generic) instance ElmType Book type BooksApi = "books" :> Capture "bookId" Int :> Get '[JSON] Book ``` Now we can generate Elm functions to query the API: ```haskell spec :: Spec spec = Spec ["Generated", "MyApi"] (defElmImports : toElmTypeSource (Proxy :: Proxy Book) : toElmDecoderSource (Proxy :: Proxy Book) : generateElmForAPI (Proxy :: Proxy BooksApi)) main :: IO () main = specsToDir [spec] "my-elm-dir" ``` Let's save this as `example.hs` and run it: ``` $ stack runghc example.hs Writing: my-elm-dir/Generated/MyApi.elm $ ``` Here's what was generated: ```elm module Generated.MyApi exposing (..) import Json.Decode exposing (..) import Json.Decode.Pipeline exposing (..) import Json.Encode import Http import String type alias Book = { name : String } decodeBook : Decoder Book decodeBook = decode Book |> required "name" string getBooksByBookId : Int -> Http.Request (Book) getBooksByBookId bookId = Http.request { method = "GET" , headers = [ Http.header "Content-Type" "application/json" ] , url = String.join "/" [ "" , "books" , bookId |> toString |> Http.encodeUri ] , body = Http.emptyBody , expect = Http.expectJson decodeBook , timeout = Nothing , withCredentials = False } ``` See [`examples`](examples) for a complete usage example, or take a look at [mattjbray/servant-elm-example-app](https://github.com/mattjbray/servant-elm-example-app) for an example project using this library. ## Development ``` $ git clone https://github.com/mattjbray/servant-elm.git $ cd servant-elm $ stack test ``` To build all examples: ``` $ make examples ``` To run an example: ``` $ cd examples/e2e-tests $ elm-reactor # Open http://localhost:8000/elm/Main.elm ```