packages feed

servant-elm 0.1.0.0 → 0.1.0.1

raw patch · 5 files changed

+201/−3 lines, 5 files

Files

+ CHANGELOG.md view
@@ -0,0 +1,8 @@+0.1.0.1+-------+* Convenience re-exports from Elm and Data.Proxy.+* Add Haddoc documentation.++0.1+---+* Initial release.
+ README.md view
@@ -0,0 +1,125 @@+# 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).++## Example++Let's get some boring language pragmas and imports out of the way.++```haskell+{-# LANGUAGE DeriveGeneric     #-}+{-# LANGUAGE DataKinds         #-}+{-# LANGUAGE TypeOperators     #-}++import           Data.Proxy   (Proxy(Proxy))+import           Elm          (Spec(Spec), ToElmType, specsToDir)+import           GHC.Generics (Generic)+import           Servant.API  ((:>), Capture, Get, JSON)+import           Servant.Elm  (defElmImports, generateElmForAPI)+```++We have some Haskell-defined types and our Servant API.++```haskell+data Book = Book+  { name :: String+  } deriving (Generic)++instance ToElmType 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+             : 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 where++import Json.Decode exposing ((:=))+import Json.Decode.Extra exposing ((|:))+import Json.Encode+import Http+import String+import Task+++type alias Book =+  { name : String+  }++decodeBook : Json.Decode.Decoder Book+decodeBook =+  Json.Decode.succeed Book+    |: ("name" := Json.Decode.string)++getBooksBy : Int -> Task.Task Http.Error (Book)+getBooksBy bookId =+  let+    request =+      { verb =+          "GET"+      , headers =+          [("Content-Type", "application/json")]+      , url =+          "/" ++ "books"+          ++ "/" ++ (bookId |> toString |> Http.uriEncode)+      , body =+          Http.empty+      }+  in+    Http.fromJson+      decodeBook+      (Http.send Http.defaultSettings request)+```++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 build+$ stack test+```++## TODO++Servant API coverage:++* MatrixFlag / MatrixParam / MatrixParams+* Header (request)+* Headers (response)+* Delete / Patch / Put / Raw+* Vault / RemoteHost / IsSecure++Other:++* Option to not use elm-export: generate functions that take a decoder and+  String arguments.
servant-elm.cabal view
@@ -1,5 +1,5 @@ name:                servant-elm-version:             0.1.0.0+version:             0.1.0.1 synopsis:            Automatically derive Elm functions to query servant webservices. description:         Please see README.md homepage:            http://github.com/mattjbray/servant-elm#readme@@ -10,7 +10,9 @@ copyright:           2015-2016 Matt Bray category:            Web build-type:          Simple--- extra-source-files:+extra-source-files:+  CHANGELOG.md+  README.md cabal-version:       >=1.10  library
src/Servant/Elm.hs view
@@ -1,11 +1,33 @@+{-|+Basic usage:++> import MyLib (MyServantApiType)+> import Servant.Elm+>+> spec :: Spec+> spec = Spec ["Generated", "MyApi"]+>             (defElmImports : generateElmForAPI (Proxy :: Proxy MyServantApiType))+>+> main :: IO ()+> main = specsToDir [spec] "my-elm-dir"+-} module Servant.Elm        ( generateElmForAPI        , generateElmForAPIWith        , ElmOptions(..)        , defElmOptions        , defElmImports+       -- * Convenience re-exports from the "Elm" module+       , Spec(Spec)+       , ToElmType+       , specsToDir+       -- * Convenience re-exports from "Data.Proxy"+       , Proxy(Proxy)        ) where  import           Servant.Elm.Generate (ElmOptions (..), defElmImports,                                        defElmOptions, generateElmForAPI,                                        generateElmForAPIWith)++import Data.Proxy (Proxy(Proxy))+import Elm (Spec(Spec), ToElmType, specsToDir)
src/Servant/Elm/Generate.hs view
@@ -11,15 +11,42 @@                                       SegmentType (..), camelCase)  +{-|+Options to configure how code is generated.+-} data ElmOptions = ElmOptions-  { urlPrefix :: String }+  { {- | The protocol, host and any path prefix to be used as the base for all+    requests. +    Example: @"https://mydomain.com/api/v1"@+    -}+    urlPrefix :: String } ++{-|+The default options for generating Elm code.++[@urlPrefix@] (An empty string)+-} defElmOptions :: ElmOptions defElmOptions = ElmOptions   { urlPrefix = "" }  +{-|+Default imports required by generated Elm code.++You probably want to include this at the top of your generated Elm module.++The default required imports are:++> import Json.Decode exposing ((:=))+> import Json.Decode.Extra exposing ((|:))+> import Json.Encode+> import Http+> import String+> import Task+-} defElmImports :: String defElmImports =   unlines@@ -32,11 +59,25 @@     ]  +{-|+Generate Elm code for the API with default options.++Returns a list of Elm code definitions with everything you need to query your+Servant API from Elm: type definitions, JSON decoders, JSON encoders, and query+functions.++You could spit these out to a file and call them from your Elm code, but you+would be better off creating a 'Spec' with the result and using 'specsToDir',+which handles the module name for you.+-} generateElmForAPI :: (HasElmClient layout)                   => Proxy layout -> [String] generateElmForAPI = generateElmForAPIWith defElmOptions  +{-|+Generate Elm code for the API with custom options.+-} generateElmForAPIWith :: (HasElmClient layout)                       => ElmOptions -> Proxy layout -> [String] generateElmForAPIWith opts = nub . concatMap (generateElmForRequest opts) . elmClient