on a008e08 help sign in
servant/example/greet.hs
100 lines 3.2 kB history raw
1{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE TypeOperators #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE OverloadedStrings #-}
6{-# OPTIONS_GHC -fno-warn-orphans #-}
7import Data.Aeson
8import Data.Proxy
9import Data.Text(Text)
10import GHC.Generics
11import Servant.API
12import Servant.Docs
14-- * Example
16-- | A greet message data type
17newtype Greet = Greet Text
18 deriving (Generic, Show)
20instance FromJSON Greet
21instance ToJSON Greet
23-- We add some useful annotations to our captures,
24-- query parameters and request body to make the docs
25-- really helpful.
26instance ToCapture (Capture "name" Text) where
27 toCapture _ = DocCapture "name" "name of the person to greet"
29instance ToCapture (Capture "greetid" Text) where
30 toCapture _ = DocCapture "greetid" "identifier of the greet msg to remove"
32instance ToParam (QueryParam "capital" Bool) where
33 toParam _ =
34 DocQueryParam "capital"
35 ["true", "false"]
36 "Get the greeting message in uppercase (true) or not (false).\
37 \Default is false."
38 Normal
40instance ToParam (MatrixParam "lang" String) where
41 toParam _ =
42 DocQueryParam "lang"
43 ["en", "sv", "fr"]
44 "Get the greeting message selected language. Default is en."
45 Normal
47instance ToSample Greet where
48 toSample = Just $ Greet "Hello, haskeller!"
50 toSamples =
51 [ ("If you use ?capital=true", Greet "HELLO, HASKELLER")
52 , ("If you use ?capital=false", Greet "Hello, haskeller")
53 ]
55intro1 :: DocIntro
56intro1 = DocIntro "On proper introductions." -- The title
57 [ "Hello there."
58 , "As documentation is usually written for humans, it's often useful \
59 \to introduce concepts with a few words." ] -- Elements are paragraphs
61intro2 :: DocIntro
62intro2 = DocIntro "This title is below the last"
63 [ "You'll also note that multiple intros are possible." ]
66-- API specification
67type TestApi =
68 -- GET /hello/:name?capital={true, false} returns a Greet as JSON
69 "hello" :> MatrixParam "lang" String :> Capture "name" Text :> QueryParam "capital" Bool :> Get Greet
71 -- POST /greet with a Greet as JSON in the request body,
72 -- returns a Greet as JSON
73 :<|> "greet" :> ReqBody Greet :> Post Greet
75 -- DELETE /greet/:greetid
76 :<|> "greet" :> Capture "greetid" Text :> Delete
78testApi :: Proxy TestApi
79testApi = Proxy
81extras :: ExtraInfo TestApi
82extras =
83 safeInfo (Proxy :: Proxy ("greet" :> Capture "greetid" Text :> Delete)) $
84 defAction & headers <>~ ["unicorns"]
85 & notes <>~ [ DocNote "Title" ["This is some text"]
86 , DocNote "Second secton" ["And some more"]
87 ]
89-- Generate the data that lets us have API docs. This
90-- is derived from the type as well as from
91-- the 'ToCapture', 'ToParam' and 'ToSample' instances from above.
92--
93-- If you didn't want intros you could just call:
94--
95-- > docs testAPI
96docsGreet :: API
97docsGreet = docsWith [intro1, intro2] extras testApi
99main :: IO ()
100main = putStrLn $ markdown docsGreet