【问题标题】:Cannot figure out how (status/forbidden!) works无法弄清楚(状态/禁止!)如何工作
【发布时间】:2015-12-17 01:42:06
【问题描述】:

我可以阅读 Ring 文档并知道(状态/禁止!)具有引发返回 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 }))))

问题是,我不明白它是如何做到的。我查看环码,在任何地方都找不到(状态/禁止!)的定义。我确实看到了...

(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"]]

【问题讨论】:

  • 除了 ring 之外,您还使用其他库吗?请从 project.clj 分享:dependencies
  • 你能链接你正在查看的代码吗?我在github.com/ring-clojure/ring中找不到defstatus@
  • @ez121sl :dependencies 添加到问题中。我认为它处于中间位置。
  • @TimothyPratley github 链接已添加到问题中

标签: clojure ring


【解决方案1】:

“魔法”在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! ...)

宏扩展为代码...在这种情况下,定义函数的代码与第一个参数的名称类似,但采用驼峰式大小写并带有尾随 bang。

【讨论】:

  • 哦,天哪。那是巫术。很好的解释。
猜你喜欢
  • 1970-01-01
  • 2017-05-19
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
相关资源
最近更新 更多