2015-12-17 4 views
2

я могу читать документы 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 })))) 

Проблема Я не понимаю, КАК это так. Я смотрю в код звонка и не могу найти def для (статус/запрещено!) В любом месте. Я вижу ...

(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, но нет '!' на нем, и Запрет - это не то же самое, что запрещено в любом случае. Какое колдовство связано с тем, чтобы этот код мог компилироваться и работать? Пожалуйста, объясни.

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"]] 
+0

Вы используете какие-либо библиотеки, кроме кольца? Пожалуйста, поделитесь «зависимостями» от project.clj. – ez121sl

+0

Можете сослаться на код, на который вы смотрите? Я не могу найти defstatus в https://github.com/ring-clojure/ring –

+0

@ ez121sl: зависимости добавлены в вопрос. По-моему, это кольцо вверх-середина. –

ответ

2

"Магия" находится в 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-ответ.

class-name запрещено

(->kebab-case Forbidden) => forbidden

(str forbidden "!") => "forbidden!"

(defn ~(symbol "fobidden!") ...) => (defn forbidden! ...)

Макросы расширения в коде ... в этом случае код для определения функции аналогично имени первого аргумента, но с верблюжьей шкурой и с длинным ударом.

+0

О, мой. Это колдовство. Отличное объяснение. –