The (perhaps slightly deceptively named) :uri
parameter is allowed to be either a string or a predicate on the request object. So, you can pass a function there that checks if the method and path match. I wrote a macro to make it prettier:
(defmacro method-path (methods path)
"Expands to a predicate the returns true of the Hunchtoot request
has a SCRIPT-NAME matching the PATH and METHOD in the list of METHODS.
You may pass a single method as a designator for the list containing
only that method."
(declare
(type (or keyword list) methods)
(type string path))
`(lambda (request)
(and (member (hunchentoot:request-method* request)
,(if (keywordp methods)
`'(,methods)
`',methods))
(string= (hunchentoot:script-name* request)
,path))))
(hunchentoot:define-easy-handler (get-handler :uri (method-path :get "/hello")) ()
"hello!")
(hunchentoot:define-easy-handler (post-handler :uri (method-path (:post :put) "/hello")) ()
"a post or a put!")
In the case where the path is found but the method isn't, we should probably return an HTTP 405 error instead of the 404 error that Hunchentoot returns when no handlers match. In order to do this, you could manually write a catch-all handler for every path you define. The 405 response is supposed to include a list of acceptable methods, and I can't think of an easy way to generate one short of modifying define-easy-handler
to support specialization on method directly, which might be a good idea.
default-requiest-type
affects only what "arguments" are considered when invoking the handler. It doesn't affect whether the handler will be called. So it seems like you are on your own implementing that. – Cellulose