compojure.core / GET接受描述URI的字符串或描述正则表达式的向量作为路由定义参数,该正则表达式除了URI本身之外还要与从URI中提取的参数匹配。您可以在此处找到文档Routes in Detail
来自我的REPL(从头开始,leiningen的project.clj在这个问题的最后)
user> (use '[compojure.core :only [GET]])
nil
user> (def h (GET "/" [] "hello"))
#'user/h
user> (h {:uri "/" :request-method :get})
{:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "hello"}
到目前为止,这么好的普通香草路线
以下是使用向量进行路由的示例:
user> (def h2 (GET ["/foo/:id" :id #"[0-9]+"] [] "hello from foo"))
#'user/h2
user> (h2 {:uri "/foo/123" :request-method :get})
{:status 200, :headers {"Content-Type" "text/html; charset=utf-8"}, :body "hello from foo"}
user> (h2 {:uri "/foo/abc" :request-method :get})
nil
仍然一切都很好;你可以看到它只匹配数字请求:id's
现在这里出现了我不明白的部分:
user> (def v ["/foo/:id" :id #"[0-9]+"])
#'user/v
user> (def h3 (GET v [] "hello again from foo"))
#'user/h3
user> (h3 {:uri "/foo/abc" :request-method :get})
IllegalArgumentException No implementation of method: :route-matches of protocol: #'clout.core/Route found for class: clojure.lang.PersistentVector clojure.core/-cache-protocol-fn (core_deftype.clj:541)
当有人使用变量而不是文字向量定义处理程序时,是否可以解释处理程序在评估时失败的原因?
如果您想要复制确切的环境,这是我的leiningen项目文件project.clj:
(defproject cljlab "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/clojure-contrib "1.2.0"]
[compojure "1.1.5"]])
答案 0 :(得分:3)
问题在于,compojure的GET是一个宏,而不是一个函数。宏在编译时运行,因此无法查看“v”的值是什么。查看为h2和h3生成的代码之间的区别:
user> (pprint (macroexpand-1 '(GET ["/foo/:id" :id #"[0-9]+"] [] "hello from foo")))
(compojure.core/make-route
:get
(clout.core/route-compile "/foo/:id" {:id #"[0-9]+"})
(clojure.core/fn
[request__1858__auto__]
(compojure.core/let-request
[[] request__1858__auto__]
"hello from foo")))
user> (pprint (macroexpand-1 '(GET v [] "hello again from foo")))
(compojure.core/make-route
:get
(if (clojure.core/string? v) (clout.core/route-compile v) v)
(clojure.core/fn
[request__1858__auto__]
(compojure.core/let-request
[[] request__1858__auto__]
"hello again from foo")))
在第一种情况下,宏能够将路径分成其成分并对其进行转换。在第二种情况下,宏只看到“v”符号。