Matching on Request Method (GET, POST, etc)

methodM and methodOnly

We can specify that a route is only valid for specific HTTP request methods by using the methodM guard:

#ifdef HsColour > methodM :: (ServerMonad m, MonadPlus m, MatchMethod method) => method -> m () #endif

The methodM guard does two things:

  1. Specifies what methods to allow
  2. Checks that all the path segments have been consumed

Here is a simple demo app:

> module Main where > > import Control.Monad (msum) > import Happstack.Server (Method(GET, POST), dir, methodM, nullConf, ok, simpleHTTP) > > main :: IO () > main = simpleHTTP nullConf $ msum > [ do methodM GET > ok $ "You did a GET request.\n" > , do methodM POST > ok $ "You did a POST request.\n" > , dir "foo" $ do methodM GET > ok $ "You did a GET request on /foo\n" > ] >

[Source code for the app is here.]

Using curl we can see the expected results for normal GET and POST requests to /:

 $ curl http://localhost:8000/
You did a GET request.
 $ curl -d '' http://localhost:8000/
You did a POST request.

Note that methodM also requires that the all the segments of request path have been consumed. We can see in here that /foo is accepted, but not /foo/bar, since only foo is consumed by the, dir "foo" filter.

 $ curl http://localhost:8000/foo
You did a GET request on /foo
 $ curl http://localhost:8000/foo/bar
<404 message>

If we want to allow unconsumed path segments we can use methodOnly instead.

#ifdef HsColour > methodOnly :: (ServerMonad m, MonadPlus m, MatchMethod method) => method -> m () #endif

In fact the definition for methodM is simply:

#ifdef HsColour > methodM :: (ServerMonad m, MonadPlus m, MatchMethod method) => method -> m () > methodM meth = methodOnly meth >> nullDir #endif