Spock - Path Parameters
This literate haskell file demonstrates how to use path 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 --package string-conv SpockPath.lhs
Extensions
{-# LANGUAGE OverloadedStrings #-}
Imports
import Data.Monoid ( (<>) )
import Data.String.Conv (toS)
import Web.Spock
( SpockM, runSpock, spock, get, text
, (<//>)
, var
, static
, wildcard
)
toS |
seamlessly converts between String, Text, and ByteString values |
<//> |
operator that combines two path components |
var |
placeholder for a path parameter |
static |
used to define a static path |
wildcard |
matches the remaining part of the path |
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 ("hola" <//> var) $ \name -> do
text ("Hola " <> name <> "! ¿Qué pasó?")
The route above handles GET
requests to /hola/<some-name>
. <//>
combined the path component "hola"
and path placeholder component introduced by var
.
Try visiting:
- http://localhost:5000/hola/amigo
- http://localhost:5000/hola/Anders
- http://localhost:5000/hola/someone/else
get ("add" <//> var <//> "to" <//> var) $ \x y -> do
text . toS . show $ (x + y :: Int)
Can you guess what the route above matches?
If you guessed /add/<x>/to/<y>
you’re correct! As you can see var
is used to introduce a placeholder in the path and <//>
combines path pieces.
Try visiting:
get (static "what-is-this") $ do
text "just some text"
The route above is equivalent to having declared it like so: get "what-is-this" $ ...
. As you can tell, static
is an alternative way to declare paths. You can learn more about why these are equivalent by completing Exercise 1.
get ("gotta" <//> wildcard) $ \rest -> do
text ("you have to: " <> rest)
wildcard
is similar to var
in that it is a placeholder. However, unlike var
, it matches the rest of the path and only gives a Text
parameter. Additionally, it must be the last component in the path specification.
Try visiting:
- http://localhost:5000/gotta
- http://localhost:5000/gotta/do/stuff
- http://localhost:5000/gotta/catch/em/all
Main
main :: IO ()
main = do
defConfig <- defaultSpockCfg EmptySession PCNoDatabase EmptyState
runSpock 5000 (spock defConfig webapp)
Exercises
(Medium) Investigate the instances of
Path
. How do you suppose Strings get converted to Paths?(Medium) Try to append a
var
to thewildcard
example above. What happens? Why do you suppose this is the case?