Как мне сделать так, чтобы промежуточное ПО помещало заголовок ответа только тогда, когда `: swagger {: deprecated true}`? - PullRequest
0 голосов
/ 27 марта 2019

Мы используем compojure-api, чтобы получить хорошую интеграцию в наши кольцевые приложения.Мета :swagger {:deprecated true} работает, как чемпион, чтобы получить правильную страницу чванства, но у меня есть требование, чтобы я добавлял специальный заголовок в ответ, когда маршрут :swagger {:deprecated true}.Я изо всех сил пытаюсь выяснить, как сделать это с шаблоном промежуточного программного обеспечения, который я использовал, чтобы сделать аналогичные манипуляции с заголовками ответа.

(ns bob.routes
  (:require [clojure.tools.logging :as log]
            [compojure.api.sweet :refer :all]
            [ring.util.http-response :as status]
            [schema.core :as s]
            [ring.swagger.schema :as rs]))

(s/defschema BobResponse {:message (rs/describe String "Message")})

(defn wrap-bob-response-header [handler]
  (fn [request]
    (let [response (handler request)]
      ;; can I reach into the request or the response to see what
      ;; route served this and if it has the :swagger {:deprecated true}
      ;; meta on it and NOT emit the x-bob header if it does?
      (assoc-in response [:headers "x-bob"] "Robert"))))

(defroutes bob-routes
  (context "" []
    :middleware [wrap-bob-response-header]
    :tags ["bob"]
    :description ["Tease out how to do swagger driven response header"]
    (GET "/notdeprectated" [:as request]
      :swagger {:deprecated false}
      :new-relic-name "GET_notdeprecated"
      :return BobResponse
      (status/ok {:message "All is well"}))
    (GET "/isdeprecated" [:as request]
      :swagger {:deprecated true}
      :new-relic-name "GET_isdeprecated"
      :return BobResponse
      (status/ok {:message "You came to the wrong neighborhood."}))))

Как мне изменить wrap-bob-response-header, чтобы только испускать x-bob намаршруты с :swagger {:deprecated true}?

1 Ответ

1 голос
/ 27 марта 2019

С Compojure-API промежуточное программное обеспечение вызывается на месте, в контексте пути, в котором они определены.В вашем примере wrap-bob-response-header еще не знает, куда направляется запрос (или он вообще будет соответствовать чему-либо).Если бы он знал, вы могли бы использовать введенную информацию о маршруте из запроса (см. https://github.com/metosin/compojure-api/blob/master/src/compojure/api/api.clj#L71-L73), чтобы определить, будут ли на конечных точках задана информация о чванстве.

Что вы можете сделать, это смонтировать заголовок-установка промежуточного программного обеспечения только для маршрутов, которым он нужен.

Существует библиотека с именем reitit (также от Metosin), которая решает эту проблему, применяя архитектуру, ориентированную на маршрут: поиск по полному пути выполненво-первых, и цепочка промежуточного программного обеспечения применяется после этого. Из-за этого все промежуточное программное обеспечение знает конечную точку, к которой они подключены. Промежуточное программное обеспечение может просто запрашивать данные конечной точки (во время запроса или во время компиляции) и действовать соответственно.даже решите не подключаться к этому специальному маршруту.

Reitit - это функция с compojure-api, только с другим синтаксисом, например, полностью управляемая данными.

Хорошие примеры в блоге: https://www.metosin.fi/blog/reitit-ring/

PS. Я являюсь соавтором обеих библиотек.

РЕДАКТИРОВАТЬ.

Решение для ввода данных в ответ послесовпадение:

1) создать промежуточное программное обеспечение, которое добавляет данные (или метаданные) к ответу

2) добавить или изменить обработчик реструктуризации для монтирования промежуточного программного обеспечения из 1 в конечную точку, сданные (доступны в обработчике)

3) считывают данные в конвейере ответов и действуют соответственно

(defn wrap-add-response-data [handler data]
  (let [with-data #(assoc % ::data data)]
    (fn
      ([request]
       (with-data (handler request)))
      ([request respond raise]
       (handler #(respond (with-data %)) raise)))))

(defmethod compojure.api.meta/restructure-param :swagger [_ swagger acc]
  (-> acc
      (assoc-in [:info :public :swagger] swagger)
      (update-in [:middleware] into `[[wrap-add-response-data ~swagger]])))

(def app
  (api
    (context "/api" []
      (GET "/:kikka" []
        :swagger {:deprecated? true}
        (ok "jeah")))))

(app {:request-method :get, :uri "/api/kukka"})
; {:status 200, :headers {}, :body "jeah", ::data {:deprecated? true}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...