我找不到任何基于HTTP方法的调度文档(在同一个uri上)。我得到的最接近的是:default-request-type
上的define-easy-handler
- 但它似乎会发送到后者,即使我使用GET方法:
(define-easy-handler (index :uri "/" :default-request-type :get) ()
(log-message* :info "GET on index ------ ")
(format nil "Hello World"))
(define-easy-handler (echo :uri "/" :default-request-type :post) ()
(log-message* :info "POST on index ------ ")
(format nil "~S" (raw-post-data :force-text t)))
答案 0 :(得分:4)
允许{(1}}参数(可能略带名称){1}}参数是请求对象上的字符串或谓词。因此,您可以在那里传递一个函数来检查方法和路径是否匹配。我写了一个宏来让它更漂亮:
:uri
在找到路径但方法不是的情况下,我们应该返回HTTP 405错误,而不是Hunchentoot在没有处理程序匹配时返回的404错误。为此,您可以为您定义的每个路径手动编写一个catch-all处理程序。 405响应应该包含一个可接受的方法列表,我想不出一个简单的方法来生成一个简单的修改(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!")
来直接支持方法的专业化,这可能是一个好主意。
答案 1 :(得分:2)
许多构建在hunchentoot之上的框架都有。 Restas和Caveman只是两个例子。例如,在Restas,您可以说:
(restas:define-route foo ("/foo" :method :get)
; some code here
)
(restas:define-route foo/post ("/foo" :method :post)
; some other code here
)
答案 2 :(得分:0)
我们现在有一个Hunchentoot附加组件可以做到这一点:easy-routes。它带来了通过HTTP方法进行分派,从url路径中提取参数以及方便的装饰器表示法。
要使用它,我们只需要使用其routes-acceptor
而不是默认的easy-acceptor
:
(hunchentoot:start (make-instance 'easy-routes:routes-acceptor))
一个例子:
(defroute foo ("/foo/:arg1/:arg2" :method :get)
(&get w)
(format nil "<h1>FOO arg1: ~a arg2: ~a ~a</h1>" arg1 arg2 w))