无法弄清楚 (status/forbidden!) 是如何工作的
Cannot figure out how (status/forbidden!) works
我可以阅读 Ring 文档并知道 (status/forbidden!) 具有引发异常的效果 returns HTTP 403。
(ns com.example.mosaic.endpoint.v2.api
(:require
; ...
[ring.util.http-response :as status]
[ring.util.response :as response])
(:import [org.joda.time DateTime]))
(defn- check-error-response!
"Translate the response from boundary server into an appropriate http error response."
[response user-id field-id]
(let [{:keys [status]} response]
(cond
(contains? #{401 403 404} status) (status/forbidden! {:error-code "BS-004" :user-id user-id :field-id field-id })
(= 500 status) (status/internal-server-error! {:error-code "BS-005" :user-id user-id :field-id field-id }))))
问题是,我不明白它是如何做到的。我查看了振铃代码,但在任何地方都找不到 (status/forbidden!) 的定义。我确实看到了一个...
(defstatus Forbidden 403 "Forbidden" "The request was a legal request but the server is refusing to respond to it.")
...在 https://github.com/metosin/ring-http-response/blob/0.5.1/src/ring/util/http_response.clj 中,但没有 '!'在它上面,并且 Forbidden 在任何情况下都不等同于禁止。允许这段代码编译和工作涉及什么魔法?请解释。
project.clj:依赖项是
:dependencies
[[org.clojure/clojure "1.6.0"]
[org.clojure/tools.cli "0.3.1"]
[org.clojure/tools.logging "0.3.0"]
[ring/ring-core "1.3.0"]
[ring/ring-jetty-adapter "1.3.0"]
[metosin/ring-swagger-ui "2.0.24"]
[metosin/ring-swagger "0.14.0"]
[metosin/compojure-api "0.15.1"]
[org.slf4j/slf4j-api "1.6.2"]
[org.slf4j/slf4j-log4j12 "1.6.2"]
[bk/ring-gzip "0.1.1"]
[com.example/field-layer "2015.04.17T16.17.30.874cd09"]
[com.cemerick/drawbridge "0.0.6"]
[clj-http "1.1.0"]
[com.example.the-request/the-clj-http "2015.04.15T00.53.11.843c71c"]
[org.apache.httpcomponents/httpclient "4.3.6"]
[com.example/compojure-api-utils "2015.03.30T23.14.19.79ff61f"]
[ring.middleware.logger "0.5.0" :exclusions [org.slf4j/slf4j-log4j12]]
[ring.middleware.conditional "0.1.0"]
[com.example/the-config "2014.11.07T23.39.35.5844ff4"]
[com.example.the-request/the-request-core "2015.04.23T22.02.36.e4ca089"]
[com.example/the-ring-middleware "2014.11.07T23.39.49.0d0d85d"]]
"magic"在defstatus
宏中:
(defmacro defstatus [class-name status name description & [options]]
参见第 29 和 45 行:
(let [...
fn-name (->kebab-case class-name)
...
`(defn ~(symbol (str fn-name "!"))
...
因此 (defstatus Forbidden ...)
扩展为 (defn forbidden! ...)
您可以通过执行以下命令查看完整的宏展开:
(macroexpand-1 '(defstatus Forbidden 403 "Forbidden" "The request was a legal request but the server is refusing to respond to it."))
在 ring.util.http-response 命名空间中。
class-name
被禁止
(->kebab-case Forbidden) => forbidden
(str forbidden "!") => "forbidden!"
(defn ~(symbol "fobidden!") ...) => (defn forbidden! ...)
宏扩展为代码...在本例中,代码定义了一个与第一个参数同名的函数,但采用驼峰式命名并带有尾部爆炸。
我可以阅读 Ring 文档并知道 (status/forbidden!) 具有引发异常的效果 returns HTTP 403。
(ns com.example.mosaic.endpoint.v2.api
(:require
; ...
[ring.util.http-response :as status]
[ring.util.response :as response])
(:import [org.joda.time DateTime]))
(defn- check-error-response!
"Translate the response from boundary server into an appropriate http error response."
[response user-id field-id]
(let [{:keys [status]} response]
(cond
(contains? #{401 403 404} status) (status/forbidden! {:error-code "BS-004" :user-id user-id :field-id field-id })
(= 500 status) (status/internal-server-error! {:error-code "BS-005" :user-id user-id :field-id field-id }))))
问题是,我不明白它是如何做到的。我查看了振铃代码,但在任何地方都找不到 (status/forbidden!) 的定义。我确实看到了一个...
(defstatus Forbidden 403 "Forbidden" "The request was a legal request but the server is refusing to respond to it.")
...在 https://github.com/metosin/ring-http-response/blob/0.5.1/src/ring/util/http_response.clj 中,但没有 '!'在它上面,并且 Forbidden 在任何情况下都不等同于禁止。允许这段代码编译和工作涉及什么魔法?请解释。
project.clj:依赖项是
:dependencies
[[org.clojure/clojure "1.6.0"]
[org.clojure/tools.cli "0.3.1"]
[org.clojure/tools.logging "0.3.0"]
[ring/ring-core "1.3.0"]
[ring/ring-jetty-adapter "1.3.0"]
[metosin/ring-swagger-ui "2.0.24"]
[metosin/ring-swagger "0.14.0"]
[metosin/compojure-api "0.15.1"]
[org.slf4j/slf4j-api "1.6.2"]
[org.slf4j/slf4j-log4j12 "1.6.2"]
[bk/ring-gzip "0.1.1"]
[com.example/field-layer "2015.04.17T16.17.30.874cd09"]
[com.cemerick/drawbridge "0.0.6"]
[clj-http "1.1.0"]
[com.example.the-request/the-clj-http "2015.04.15T00.53.11.843c71c"]
[org.apache.httpcomponents/httpclient "4.3.6"]
[com.example/compojure-api-utils "2015.03.30T23.14.19.79ff61f"]
[ring.middleware.logger "0.5.0" :exclusions [org.slf4j/slf4j-log4j12]]
[ring.middleware.conditional "0.1.0"]
[com.example/the-config "2014.11.07T23.39.35.5844ff4"]
[com.example.the-request/the-request-core "2015.04.23T22.02.36.e4ca089"]
[com.example/the-ring-middleware "2014.11.07T23.39.49.0d0d85d"]]
"magic"在defstatus
宏中:
(defmacro defstatus [class-name status name description & [options]]
参见第 29 和 45 行:
(let [...
fn-name (->kebab-case class-name)
...
`(defn ~(symbol (str fn-name "!"))
...
因此 (defstatus Forbidden ...)
扩展为 (defn forbidden! ...)
您可以通过执行以下命令查看完整的宏展开:
(macroexpand-1 '(defstatus Forbidden 403 "Forbidden" "The request was a legal request but the server is refusing to respond to it."))
在 ring.util.http-response 命名空间中。
class-name
被禁止
(->kebab-case Forbidden) => forbidden
(str forbidden "!") => "forbidden!"
(defn ~(symbol "fobidden!") ...) => (defn forbidden! ...)
宏扩展为代码...在本例中,代码定义了一个与第一个参数同名的函数,但采用驼峰式命名并带有尾部爆炸。