servant-cli alternatives and similar packages
Based on the "servant" category.
Alternatively, view servant-cli alternatives based on common mentions on social networks and blogs.
-
servant
Main repository for the servant libraries — DSL for describing, serving, querying, mocking, documenting web applications and more! -
servant-elm
Automatically derive Elm functions to query servant webservices -
servant-purescript
Translate servant API to purescript code, with the help of purescript-bridge. -
servant-swagger-ui
Provide embedded swagger UI for servant and swagger -
servant-js
Automatically derive javascript functions to query servant webservices. -
servant-aeson-specs
Generically obtain tests for JSON serialization -
servant-pandoc
Render a servant API to Pandoc's native representation -
servant-github-webhook
Servant combinators for writing secure GitHub webhooks -
servant-mock
Derive a mock server for free from your servant API types -
servant-matrix-param
Matrix parameter combinator for servant -
servant-auth-token-acid
Servant based API and server for token based authorisation -
servant-auth-token-leveldb
Servant based API and server for token based authorisation -
servant-jsonrpc
Tools to build JSON-RPC clients and servers the Servant way -
servant-reason
Automatically derive bindings for Servant APIs in Reason -
servant-kotlin
Automatically derive Kotlin functions to query servant webservices -
servant-http2-client
Generate http2-client from Servant APIs -
servant-ruby
Create a Ruby client from a Servant API using Net::HTTP. -
servant-match
Standalone implementation of servant’s dispatching mechanism -
servant-options
Provide responses to OPTIONS requests for Servant applications. -
servant-generate
Generate default implementations for servers in a flexible way (a.k.a servant-mock on steroids) -
servant-proto-lens
Servant Content-Type for proto-lens protobuf modules. -
servant-haxl-client
automatical derivation of querying functions for servant webservices -
servant-multipart
multipart/form-data (e.g file upload) support for servant
TestGPT | Generating meaningful tests for busy devs
Do you think we are missing an alternative of servant-cli or a related project?
README
servant-cli
Parse command line arguments into a servant client, from a servant API, using optparse-applicative for parsing, displaying help, and auto-completion.
Hooks into the annotation system used by servant-docs to provide descriptions for parameters and captures.
See example/greet.hs
for a sample program.
Getting started
We're going to break down the example program in example/greet.hs
.
Here's a sample API revolving around greeting and some deep paths, with authentication.
type TestApi =
Summary "Send a greeting"
:> "hello"
:> Capture "name" Text
:> QueryParam "capital" Bool
:> Get '[JSON] Text
:<|> Summary "Greet utilities"
:> "greet"
:> ( Get '[JSON] Int
:<|> Post '[JSON] NoContent
)
:<|> Summary "Deep paths test"
:> "dig"
:> "down"
:> "deep"
:> Summary "Almost there"
:> Capture "name" Text
:> "more"
:> Summary "We made it"
:> Get '[JSON] Text
testApi :: Proxy TestApi
testApi = Proxy
To parse this, we can use parseClient
, which generates a client action that
we can run:
main :: IO ()
main = do
c <- parseClient testApi (Proxy :: Proxy ClientM) $
header "greet"
<> progDesc "Greet API"
manager' <- newManager defaultManagerSettings
res <- runClientM c $
mkClientEnv manager' (BaseUrl Http "localhost" 8081 "")
case res of
Left e -> throwIO e
Right r -> putStrLn $ case r of
Left g -> "Greeting: " ++ T.unpack g
Right (Left (Left i)) -> show i ++ " returned"
Right (Left (Right _)) -> "Posted!"
Right (Right s) -> s
Note that parseClient
and other functions all take InfoMod
s from
optparse-applicative, to customize how the top-level --help
is displayed.
The result will be a bunch of nested Either
s for each :<|>
branch and
endpoint. However, this can be somewhat tedious to handle.
With Handlers
The library also offers parseHandleClient
, which accepts nested :<|>
s with
handlers for each endpoint, mirroring the structure of the API:
main :: IO ()
main = do
c <- parseHandleClient testApi (Proxy :: Proxy ClientM)
(header "greet" <> progDesc "Greet API") $
(\g -> "Greeting: " ++ T.unpack g)
:<|> ( (\i -> show i ++ " returned")
:<|> (\_ -> "Posted!")
)
:<|> id
manager' <- newManager defaultManagerSettings
res <- runClientM c $
mkClientEnv manager' (BaseUrl Http "localhost" 8081 "")
case res of
Left e -> throwIO e
Right r -> putStrLn r
The handlers essentially let you specify how to sort each potential endpoint's response into a single output value.
Clients that need context
Things get slightly more complicated when your client requires something that can't be passed in through the command line, such as authentication information (username, password).
type TestApi =
Summary "Send a greeting"
:> "hello"
:> Capture "name" Text
:> QueryParam "capital" Bool
:> Get '[JSON] Text
:<|> Summary "Greet utilities"
:> "greet"
:> ( Get '[JSON] Int
:<|> BasicAuth "login" Int -- ^ Adding 'BasicAuth'
:> Post '[JSON] NoContent
)
:<|> Summary "Deep paths test"
:> "dig"
:> "down"
:> "deep"
:> Summary "Almost there"
:> Capture "name" Text
:> "more"
:> Summary "We made it"
:> Get '[JSON] Text
For this, you can pass in a context, using parseClientWithContext
or
parseHandleClientWithContext
:
main :: IO ()
main = do
c <- parseHandleClientWithContext
testApi
(Proxy :: Proxy ClientM)
(getPwd :& RNil)
(header "greet" <> progDesc "Greet API") $
(\g -> "Greeting: " ++ T.unpack g)
:<|> ( (\i -> show i ++ " returned")
:<|> (\_ -> "Posted!")
)
:<|> id
manager' <- newManager defaultManagerSettings
res <- runClientM c $
mkClientEnv manager' (BaseUrl Http "localhost" 8081 "")
case res of
Left e -> throwIO e
Right r -> putStrLn r
where
getPwd :: ContextFor ClientM (BasicAuth "login" Int)
getPwd = GenBasicAuthData . liftIO $ do
putStrLn "Authentication needed for this action!"
putStrLn "Enter username:"
n <- BS.getLine
putStrLn "Enter password:"
p <- BS.getLine
pure $ BasicAuthData n p