@@ -45,24 +45,26 @@ alice :: Person
45alice = Person "Alice" 42
45alice = Person "Alice" 42
48− "get" :> Get Person
48+ "get" :> Get '[JSON] Person
49 :<|> "delete" :> Delete
49 :<|> "delete" :> Delete
50− :<|> "capture" :> Capture "name" String :> Get Person
50+ :<|> "capture" :> Capture "name" String :> Get '[JSON] Person
51− :<|> "body" :> ReqBody Person :> Post Person
51+ :<|> "body" :> ReqBody '[JSON] Person :> Post '[JSON] Person
52− :<|> "param" :> QueryParam "name" String :> Get Person
52+ :<|> "param" :> QueryParam "name" String :> Get '[JSON] Person
53− :<|> "params" :> QueryParams "names" String :> Get [Person]
53+ :<|> "params" :> QueryParams "names" String :> Get '[JSON] [Person]
54− :<|> "flag" :> QueryFlag "flag" :> Get Bool
54+ :<|> "flag" :> QueryFlag "flag" :> Get '[JSON] Bool
55− :<|> "matrixparam" :> MatrixParam "name" String :> Get Person
56+ :<|> "matrixparam" :> MatrixParam "name" String :> Get '[JSON] Person
56− :<|> "matrixparams" :> MatrixParams "name" String :> Get [Person]
57+ :<|> "matrixparams" :> MatrixParams "name" String :> Get '[JSON] [Person]
57− :<|> "matrixflag" :> MatrixFlag "flag" :> Get Bool
58+ :<|> "matrixflag" :> MatrixFlag "flag" :> Get '[JSON] Bool
58 :<|> "rawSuccess" :> Raw
60 :<|> "rawSuccess" :> Raw
59 :<|> "rawFailure" :> Raw
61 :<|> "rawFailure" :> Raw
60 :<|> "multiple" :>
62 :<|> "multiple" :>
61 Capture "first" String :>
63 Capture "first" String :>
62 QueryParam "second" Int :>
64 QueryParam "second" Int :>
63 QueryFlag "third" :>
65 QueryFlag "third" :>
64− ReqBody [(String, [Rational])] :>
66+ ReqBody '[JSON] [(String, [Rational])] :>
65− Get (String, Maybe Int, Bool, [(String, [Rational])])
67+ Get '[JSON] (String, Maybe Int, Bool, [(String, [Rational])])
66api :: Proxy Api
68api :: Proxy Api
67api = Proxy
69api = Proxy
@@ -78,12 +80,14 @@ server = serve api (
78 Nothing -> left (400, "missing parameter"))
80 Nothing -> left (400, "missing parameter"))
79 :<|> (\ names -> return (zipWith Person names [0..]))
81 :<|> (\ names -> return (zipWith Person names [0..]))
80 :<|> return
82 :<|> return
81 :<|> (\ name -> case name of
84 :<|> (\ name -> case name of
82 Just "alice" -> return alice
85 Just "alice" -> return alice
83 Just name -> left (400, name ++ " not found")
86 Just name -> left (400, name ++ " not found")
84 Nothing -> left (400, "missing parameter"))
87 Nothing -> left (400, "missing parameter"))
85 :<|> (\ names -> return (zipWith Person names [0..]))
88 :<|> (\ names -> return (zipWith Person names [0..]))
86 :<|> return
89 :<|> return
87 :<|> (\ _request respond -> respond $ responseLBS ok200 [] "rawSuccess")
91 :<|> (\ _request respond -> respond $ responseLBS ok200 [] "rawSuccess")
88 :<|> (\ _request respond -> respond $ responseLBS badRequest400 [] "rawFailure")
92 :<|> (\ _request respond -> respond $ responseLBS badRequest400 [] "rawFailure")
89 :<|> \ a b c d -> return (a, b, c, d)
93 :<|> \ a b c d -> return (a, b, c, d)
@@ -99,9 +103,11 @@ getBody :: Person -> BaseUrl -> EitherT String IO Person
99getQueryParam :: Maybe String -> BaseUrl -> EitherT String IO Person
103getQueryParam :: Maybe String -> BaseUrl -> EitherT String IO Person
100getQueryParams :: [String] -> BaseUrl -> EitherT String IO [Person]
104getQueryParams :: [String] -> BaseUrl -> EitherT String IO [Person]
101getQueryFlag :: Bool -> BaseUrl -> EitherT String IO Bool
105getQueryFlag :: Bool -> BaseUrl -> EitherT String IO Bool
102getMatrixParam :: Maybe String -> BaseUrl -> EitherT String IO Person
107getMatrixParam :: Maybe String -> BaseUrl -> EitherT String IO Person
103getMatrixParams :: [String] -> BaseUrl -> EitherT String IO [Person]
108getMatrixParams :: [String] -> BaseUrl -> EitherT String IO [Person]
104getMatrixFlag :: Bool -> BaseUrl -> EitherT String IO Bool
109getMatrixFlag :: Bool -> BaseUrl -> EitherT String IO Bool
105getRawSuccess :: Method -> BaseUrl -> EitherT String IO (Int, ByteString, MediaType)
111getRawSuccess :: Method -> BaseUrl -> EitherT String IO (Int, ByteString, MediaType)
106getRawFailure :: Method -> BaseUrl -> EitherT String IO (Int, ByteString, MediaType)
112getRawFailure :: Method -> BaseUrl -> EitherT String IO (Int, ByteString, MediaType)
107getMultiple :: String -> Maybe Int -> Bool -> [(String, [Rational])]
113getMultiple :: String -> Maybe Int -> Bool -> [(String, [Rational])]
@@ -114,9 +120,11 @@ getMultiple :: String -> Maybe Int -> Bool -> [(String, [Rational])]
114 :<|> getQueryParam
120 :<|> getQueryParam
115 :<|> getQueryParams
121 :<|> getQueryParams
116 :<|> getQueryFlag
122 :<|> getQueryFlag
117 :<|> getMatrixParam
124 :<|> getMatrixParam
118 :<|> getMatrixParams
125 :<|> getMatrixParams
119 :<|> getMatrixFlag
126 :<|> getMatrixFlag
120 :<|> getRawSuccess
128 :<|> getRawSuccess
121 :<|> getRawFailure
129 :<|> getRawFailure
122 :<|> getMultiple)
130 :<|> getMultiple)
@@ -152,6 +160,7 @@ spec = do
152 it (show flag) $ withServer $ \ host -> do
160 it (show flag) $ withServer $ \ host -> do
153 runEitherT (getQueryFlag flag host) `shouldReturn` Right flag
161 runEitherT (getQueryFlag flag host) `shouldReturn` Right flag
155 it "Servant.API.MatrixParam" $ withServer $ \ host -> do
164 it "Servant.API.MatrixParam" $ withServer $ \ host -> do
156 runEitherT (getMatrixParam (Just "alice") host) `shouldReturn` Right alice
165 runEitherT (getMatrixParam (Just "alice") host) `shouldReturn` Right alice
157 Left result <- runEitherT (getMatrixParam (Just "bob") host)
166 Left result <- runEitherT (getMatrixParam (Just "bob") host)
@@ -166,6 +175,7 @@ spec = do
166 forM_ [False, True] $ \ flag ->
175 forM_ [False, True] $ \ flag ->
167 it (show flag) $ withServer $ \ host -> do
176 it (show flag) $ withServer $ \ host -> do
168 runEitherT (getMatrixFlag flag host) `shouldReturn` Right flag
177 runEitherT (getMatrixFlag flag host) `shouldReturn` Right flag
170 it "Servant.API.Raw on success" $ withServer $ \ host -> do
180 it "Servant.API.Raw on success" $ withServer $ \ host -> do
171 runEitherT (getRawSuccess methodGet host) `shouldReturn` Right (200, "rawSuccess", "application"//"octet-stream")
181 runEitherT (getRawSuccess methodGet host) `shouldReturn` Right (200, "rawSuccess", "application"//"octet-stream")
@@ -184,9 +194,9 @@ spec = do
186 context "client correctly handles error status codes" $ do
196 context "client correctly handles error status codes" $ do
187− let test :: WrappedApi -> Spec
197+ let test :: (WrappedApi, String) -> Spec
188− test (WrappedApi api) =
198+ test (WrappedApi api, desc) =
189− it (show (typeOf api)) $
199+ it desc $
190 withWaiDaemon (return (serve api (left (500, "error message")))) $
200 withWaiDaemon (return (serve api (left (500, "error message")))) $
191 \ host -> do
201 \ host -> do
192 let getResponse :: BaseUrl -> EitherT String IO ()
202 let getResponse :: BaseUrl -> EitherT String IO ()
@@ -194,16 +204,15 @@ spec = do
194 Left result <- runEitherT (getResponse host)
204 Left result <- runEitherT (getResponse host)
195 result `shouldContain` "error message"
205 result `shouldContain` "error message"
196 mapM_ test $
206 mapM_ test $
197− (WrappedApi (Proxy :: Proxy Delete)) :
207+ (WrappedApi (Proxy :: Proxy Delete), "Delete") :
198− (WrappedApi (Proxy :: Proxy (Get ()))) :
208+ (WrappedApi (Proxy :: Proxy (Get '[JSON] ())), "Delete") :
199− (WrappedApi (Proxy :: Proxy (Post ()))) :
209+ (WrappedApi (Proxy :: Proxy (Post '[JSON] ())), "Delete") :
200− (WrappedApi (Proxy :: Proxy (Put ()))) :
210+ (WrappedApi (Proxy :: Proxy (Put '[JSON] ())), "Delete") :
203data WrappedApi where
213data WrappedApi where
204 WrappedApi :: (HasServer api, Server api ~ EitherT (Int, String) IO a,
214 WrappedApi :: (HasServer api, Server api ~ EitherT (Int, String) IO a,
205− HasClient api, Client api ~ (BaseUrl -> EitherT String IO ()),
215+ HasClient api, Client api ~ (BaseUrl -> EitherT String IO ())) =>
207 Proxy api -> WrappedApi
216 Proxy api -> WrappedApi