Spock - Query Parameters
This literate haskell file demonstrates how to use query parameters with Spock. A copy of this runnable file is available here. You may run it via stack with the following command:
stack --resolver lts-9.14 runghc --package Spock SpockParam.lhs
Extensions
{-# LANGUAGE OverloadedStrings #-}
Imports
import Data.Monoid ( (<>) )
import Web.Spock
( SpockM, runSpock, spock, get, text
, param
, param'
)
param |
reads a request parameter (first from POST variables and then GET query parameters) |
param' |
like param above but throws an error if the request parameter is missing |
import Web.Spock.Config
( PoolOrConn (PCNoDatabase)
, defaultSpockCfg
)
Data types
data AppSession = EmptySession
data AppState = EmptyState
Web application definition
webapp :: SpockM () AppSession AppState ()
webapp = do
get "hello" $ do
mName <- param "name"
case mName of
Nothing ->
text ("Hello stranger! Sorry, I did not get your name.")
Just name ->
text ("Hello " <> name <> "! Nice to meet you.")
The route above handles GET /hello
and looks for a query parameter named name
. Note that we are forced to handle the absence of the name
query parameter since param
returns a Maybe
.
Try visiting:
get "howdy" $ do
name <- param' "name"
text ("Howdy " <> name <> "! How goes it?")
This last route handles GET /howdy
and requires the name
query parameter to be present.
Try visiting:
Main
main :: IO ()
main = do
defConfig <- defaultSpockCfg EmptySession PCNoDatabase EmptyState
runSpock 5000 (spock defConfig webapp)
Notes
param
and param'
have a Typeclass constraint of FromHttpApiData
. This means that you can use param
and param'
for any type that has instances of FromHttpApiData
including your own! For the full list of types that have instances of FromHttpApiData
check the docs here.
Exercises
(Easy) Add a route
GET /add
that takes two query parametersx
andy
and responds with the the sum of the two numbers.(Medium) Change the above route to return a nice/helpful message when one or both parameters are missing. Hint: use the
Maybe
monad to avoid having nested pattern matching.(Easy/Medium) Add a few routes which take different types of query parameters — e.g.
Bool
,Double
,Natural
,UTCTime
.- Hint: have a look at
FromHTttpApiData
mentioned in the Notes.
- Hint: have a look at