Skip to content

Instantly share code, notes, and snippets.

@chrisdone
Last active April 10, 2019 10:19
Show Gist options
  • Save chrisdone/8a506d3a6f22a297ab984e4aa7b5ea5f to your computer and use it in GitHub Desktop.
Save chrisdone/8a506d3a6f22a297ab984e4aa7b5ea5f to your computer and use it in GitHub Desktop.
Servant examples
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings #-}
-- Just an API description, no service
import Servant.API
type MyAPI = EmptyAPI
main = pure ()
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators #-}
-- An empty server
import Servant.API
import Network.Wai.Handler.Warp
import Servant
type MyAPI = EmptyAPI
app :: Application
app = serve (Proxy :: Proxy MyAPI) emptyEndpoint
emptyEndpoint :: Tagged Handler EmptyServer
emptyEndpoint = emptyServer
main :: IO ()
main = run 3001 app
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators, DeriveGeneric #-}
-- Demonstrates the POST method
import GHC.Generics
import Data.Aeson
import Servant.API
import Network.Wai.Handler.Warp
import Servant
data User = User {
name :: String,
age :: Int,
email :: String
} deriving (Generic)
instance FromJSON User
instance ToJSON User
type MyAPI = Post '[JSON] [User]
app :: Application
app = serve (Proxy :: Proxy MyAPI) emptyEndpoint
emptyEndpoint :: Handler [User]
emptyEndpoint = pure [User {name = "Billy", age = 43, email = "[email protected]"}]
main :: IO ()
main = run 3001 app
{-
POST http://localhost:3001/
[
{
"name": "Billy",
"age": 43,
"email": "[email protected]"
}
]
// POST http://localhost:3001/
// HTTP/1.1 200 OK
// Transfer-Encoding: chunked
// Date: Wed, 10 Apr 2019 09:28:39 GMT
// Server: Warp/3.2.25
// Content-Type: application/json;charset=utf-8
// Request duration: 0.036818s
-}
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators, DeriveGeneric #-}
-- Demonstrates strings in URLs.
import GHC.Generics
import Data.Aeson
import Servant.API
import Network.Wai.Handler.Warp
import Servant
data User = User {
name :: String,
age :: Int,
email :: String
} deriving (Generic)
instance FromJSON User
instance ToJSON User
type MyAPI = "user" :> Post '[JSON] [User]
app :: Application
app = serve (Proxy :: Proxy MyAPI) emptyEndpoint
emptyEndpoint :: Handler [User]
emptyEndpoint = pure [User {name = "Billy", age = 43, email = "[email protected]"}]
main :: IO ()
main = run 3001 app
{-
POST http://localhost:3001/user
[
{
"name": "Billy",
"age": 43,
"email": "[email protected]"
}
]
// POST http://localhost:3001/
// HTTP/1.1 200 OK
// Transfer-Encoding: chunked
// Date: Wed, 10 Apr 2019 09:28:39 GMT
// Server: Warp/3.2.25
// Content-Type: application/json;charset=utf-8
// Request duration: 0.036818s
-}
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators, DeriveGeneric #-}
-- Demonstrates request body handling.
import GHC.Generics
import Data.Aeson
import Servant.API
import Network.Wai.Handler.Warp
import Servant
data User = User {
name :: String,
age :: Int,
email :: String
} deriving (Generic)
instance FromJSON User
instance ToJSON User
type MyAPI = "update-user" :> ReqBody '[JSON] User :> Post '[JSON] [User]
app :: Application
app = serve (Proxy :: Proxy MyAPI) userEndpoint
userEndpoint :: User -> Handler [User]
userEndpoint user = pure [User {name = "Billy", age = 43, email = "[email protected]"}]
main :: IO ()
main = run 3001 app
{-
POST http://localhost:3001/update-user
Content-type: application/json
{"name": "Isaac Newton", "age": 372, "email": "[email protected]"}
=>
[
{
"name": "Billy",
"age": 43,
"email": "[email protected]"
}
]
// POST http://localhost:3001/update-user
// HTTP/1.1 200 OK
// Transfer-Encoding: chunked
// Date: Wed, 10 Apr 2019 09:36:41 GMT
// Server: Warp/3.2.25
// Content-Type: application/json;charset=utf-8
// Request duration: 0.027111s
-}
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators, DeriveGeneric #-}
-- Demonstrates alternative URLs and using request body.
import Data.Aeson
import Data.Char
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Generics
import Network.Wai.Handler.Warp
import Servant
import Servant.API
data User = User {
name :: String,
age :: Int,
email :: String
} deriving (Generic)
instance FromJSON User
instance ToJSON User
type MyAPI = "update-user" :> ReqBody '[JSON] User :> Post '[JSON] [User]
:<|> "upcase-name" :> ReqBody '[JSON] User :> Post '[JSON] User
app :: Application
app = serve (Proxy :: Proxy MyAPI) (userEndpoint :<|> upcase)
userEndpoint :: User -> Handler [User]
userEndpoint user = pure [User {name = "Billy", age = 43, email = "[email protected]"}]
upcase :: User -> Handler User
upcase user = pure (user {name = map toUpper (name user)})
main :: IO ()
main = run 3001 app
{-
POST http://localhost:3001/upcase-name
Content-type: application/json
{"name": "Isaac Newton", "age": 372, "email": "[email protected]"}
=>
{
"name": "ISAAC NEWTON",
"age": 372,
"email": "[email protected]"
}
// POST http://localhost:3001/upcase-name
// HTTP/1.1 200 OK
// Transfer-Encoding: chunked
// Date: Wed, 10 Apr 2019 09:43:40 GMT
// Server: Warp/3.2.25
// Content-Type: application/json;charset=utf-8
// Request duration: 0.041686s
-}
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators, DeriveGeneric #-}
-- Demonstrates strings in URLs.
import Data.Aeson
import Data.Char
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Generics
import Network.Wai.Handler.Warp
import Servant
import Servant.API
data User = User {
name :: String,
age :: Int,
email :: String
} deriving (Generic)
instance FromJSON User
instance ToJSON User
type MyAPI = "update-user" :> ReqBody '[JSON] User :> Post '[JSON] [User]
:<|> "upcase-name" :> ReqBody '[JSON] User :> Post '[JSON] User
:<|> "take-name" :> QueryParam "chars" Int :> ReqBody '[JSON] User :> Post '[JSON] User
app :: Application
app = serve (Proxy :: Proxy MyAPI) (userEndpoint :<|> upcase :<|> takename)
userEndpoint :: User -> Handler [User]
userEndpoint user = pure [User {name = "Billy", age = 43, email = "[email protected]"}]
upcase :: User -> Handler User
upcase user = pure (user {name = map toUpper (name user)})
takename :: Maybe Int -> User -> Handler User
takename cs user = pure (user {name = take (fromMaybe 0 cs) (name user)})
main :: IO ()
main = run 3001 app
{-
POST http://localhost:3001/take-name?chars=3
Content-type: application/json
{"name": "Isaac Newton", "age": 372, "email": "[email protected]"}
=>
{
"name": "Isa",
"age": 372,
"email": "[email protected]"
}
// POST http://localhost:3001/take-name?chars=3
// HTTP/1.1 200 OK
// Transfer-Encoding: chunked
// Date: Wed, 10 Apr 2019 09:49:38 GMT
// Server: Warp/3.2.25
// Content-Type: application/json;charset=utf-8
// Request duration: 0.037865s
-}
#!/usr/bin/env stack
-- stack --resolver lts-12.12 script
{-# LANGUAGE OverloadedStrings, DataKinds, TypeOperators, DeriveGeneric #-}
-- Demonstrates strings in URLs.
import Data.Aeson
import Data.Char
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Generics
import Network.Wai.Handler.Warp
import Servant
import Servant.API
data User = User {
name :: String,
age :: Int,
email :: String
} deriving (Generic)
instance FromJSON User
instance ToJSON User
type MyAPI = "update-user" :> ReqBody '[JSON] User :> Post '[JSON] [User]
:<|> "upcase-name" :> ReqBody '[JSON] User :> Post '[JSON] User
:<|> "take-name" :> QueryParam "chars" Int :> ReqBody '[JSON] User :>
Post '[JSON] (Headers '[Header "Remaining-Characters" Int] User)
app :: Application
app = serve (Proxy :: Proxy MyAPI) (userEndpoint :<|> upcase :<|> takename)
userEndpoint :: User -> Handler [User]
userEndpoint user = pure [User {name = "Billy", age = 43, email = "[email protected]"}]
upcase :: User -> Handler User
upcase user = pure (user {name = map toUpper (name user)})
takename :: Maybe Int -> User -> Handler (Headers '[Header "Remaining-Characters" Int] User)
takename cs user =
pure
(addHeader
(maybe (length (name user)) (length (name user) -) cs)
(user {name = take (fromMaybe 0 cs) (name user)}))
main :: IO ()
main = run 3001 app
{-
POST http://localhost:3001/take-name?chars=3
Content-type: application/json
{"name": "Isaac Newton", "age": 372, "email": "[email protected]"}
=>
{
"name": "Isa",
"age": 372,
"email": "[email protected]"
}
// POST http://localhost:3001/take-name?chars=3
// HTTP/1.1 200 OK
// Transfer-Encoding: chunked
// Date: Wed, 10 Apr 2019 09:55:28 GMT
// Server: Warp/3.2.25
// Content-Type: application/json;charset=utf-8
// Remaining-Characters: 9 <-----------
// Request duration: 0.035376s
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment