on master help sign in
servant-elm/README.md
151 lines 3.5 kB history raw
1# Servant Elm
3[![Build Status](https://travis-ci.org/haskell-servant/servant-elm.svg?branch=master)](https://travis-ci.org/haskell-servant/servant-elm)
5Generate Elm functions to query your Servant API!
7Elm type generation coutesy of [elm-bridge](http://hackage.haskell.org/package/elm-bridge).
9## Installation
11Servant Elm is [available on Hackage](http://hackage.haskell.org/package/servant-elm).
13## Example
15First, some language pragmas and imports.
17```haskell
18{-# LANGUAGE DataKinds #-}
19{-# LANGUAGE OverloadedStrings #-}
20{-# LANGUAGE TemplateHaskell #-}
21{-# LANGUAGE TypeOperators #-}
23import Elm.Derive (defaultOptions, deriveBoth)
25import Servant.API ((:>), Capture, Get, JSON)
26import Servant.Elm (DefineElm (DefineElm), Proxy (Proxy), defElmImports, defElmOptions,
27 generateElmModuleWith)
28```
30We have some Haskell-defined types and our Servant API.
32```haskell
33data Book = Book
34 { name :: String
35 }
37deriveBoth defaultOptions ''Book
39type BooksApi = "books" :> Capture "bookId" Int :> Get '[JSON] Book
40```
42Now we can generate Elm functions to query the API:
44```haskell
45main :: IO ()
46main =
47 generateElmModuleWith
48 defElmOptions
49 [ "Generated"
50 , "MyApi"
51 ]
52 defElmImports
53 "my-elm-dir"
54 [ DefineElm (Proxy :: Proxy Book)
55 ]
56 (Proxy :: Proxy BooksApi)
57```
59Let's save this as `example.hs` and run it:
61```
62$ stack runghc example.hs
63Writing: my-elm-dir/Generated/MyApi.elm
64```
66Here's what was generated:
68```elm
69module Generated.MyApi exposing(..)
71import Json.Decode
72import Json.Encode exposing (Value)
73-- The following module comes from bartavelle/json-helpers
74import Json.Helpers exposing (..)
75import Dict exposing (Dict)
76import Set
77import Http
78import String
79import Url.Builder
81type alias Book =
82 { name: String
83 }
85jsonDecBook : Json.Decode.Decoder ( Book )
86jsonDecBook =
87 Json.Decode.succeed (\pname -> {name = pname})
88 |> required "name" (Json.Decode.string)
90jsonEncBook : Book -> Value
91jsonEncBook val =
92 Json.Encode.object
93 [ ("name", Json.Encode.string val.name)
94 ]
97getBooksByBookId : Int -> Http.Request Book
98getBooksByBookId capture_bookId =
99 let
100 params =
101 List.filterMap identity
102 (List.concat
103 [])
104 in
105 Http.request
106 { method =
107 "GET"
108 , headers =
109 []
110 , url =
111 Url.Builder.absolute
112 [ "books"
113 , capture_bookId |> String.fromInt
114 ]
115 params
116 , body =
117 Http.emptyBody
118 , expect =
119 Http.expectJson <| jsonDecBook
120 , timeout =
121 Nothing
122 , withCredentials =
123 False
124 }
125```
127See [`examples`](examples) for a complete usage example, or take a look at
128[`mattjbray/servant-elm-example-app`](https://github.com/mattjbray/servant-elm-example-app) (elm 0.18) or [`haskell-servant/example-servant-elm`](https://github.com/haskell-servant/example-servant-elm) (elm 0.19) for an example project using this library.
130## Development
132```
133$ git clone https://github.com/mattjbray/servant-elm.git
134$ cd servant-elm
135$ stack test
136$ stack test --flag servant-elm:integration
137```
139To build all examples:
141```
142$ make examples
143```
145To run an example:
147```
148$ cd examples/e2e-tests
149$ elm-reactor
150# Open http://localhost:8000/elm/Main.elm
151```