From 210fbb9535058d93fa9bbe59f8fbd1e79cb02491 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 13 Jun 2019 21:25:09 +0200 Subject: [PATCH] feat(backend): move almost all middlewares to api.middleware ns --- backend/src/uxbox/api.clj | 58 ++----------- backend/src/uxbox/api/middleware.clj | 117 ++++++++++++++++++--------- backend/src/uxbox/api/pages.clj | 26 ++++-- 3 files changed, 106 insertions(+), 95 deletions(-) diff --git a/backend/src/uxbox/api.clj b/backend/src/uxbox/api.clj index 55c05120c..af29e0a9e 100644 --- a/backend/src/uxbox/api.clj +++ b/backend/src/uxbox/api.clj @@ -6,28 +6,13 @@ (ns uxbox.api (:require [mount.core :refer [defstate]] - [clojure.pprint :refer [pprint]] [uxbox.config :as cfg] - [ring.middleware.session :refer [wrap-session]] - [ring.middleware.session.cookie :refer [cookie-store]] [ring.adapter.jetty :as jetty] - [promesa.core :as p] - [reitit.core :as rc] [reitit.ring :as ring] - [reitit.ring.middleware.muuntaja :as muuntaja] - [reitit.ring.middleware.multipart :as multipart] - [reitit.ring.middleware.parameters :as parameters] - ;; [reitit.dev.pretty :as pretty] - [uxbox.api.middleware :as api-middleware :refer [handler]] + [uxbox.api.middleware :refer [handler router-options]] [uxbox.api.auth :as api-auth] - [uxbox.api.projects :as api-projects] [uxbox.api.pages :as api-pages] - [uxbox.api.errors :as api-errors] - [muuntaja.core :as m] - [uxbox.util.transit :as t] - [uxbox.util.data :refer [normalize-attrs]] - [uxbox.util.exceptions :as ex] - [uxbox.util.uuid :as uuid])) + [uxbox.api.projects :as api-projects])) ;; --- Top Level Handlers @@ -59,44 +44,15 @@ ["/projects/by-token/:token" {:get (handler #'api-projects/get-by-share-token)}] ["/projects/:id" {:put (handler #'api-projects/update) :delete (handler #'api-projects/delete)}] - ["/pages" {:get (handler #'api-pages/list)}] + ["/pages" {:get (handler #'api-pages/list) + :post (handler #'api-pages/create)}] ["/pages/:id" {:put (handler #'api-pages/update) :delete (handler #'api-pages/delete)}] - ["/pages/:id/metatata" {:put (handler #'api-pages/update-metadata)}] + ["/pages/:id/metadata" {:put (handler #'api-pages/update-metadata)}] ["/pages/:id/history" {:get (handler #'api-pages/retrieve-history)}] + ["/pages/:id/history/:hid" {:put (handler #'api-pages/update-history)}] ]] - - {;;:reitit.middleware/transform dev/print-request-diffs - :data {:muuntaja (m/create - (update-in m/default-options [:formats "application/transit+json"] - merge {:encoder-opts {:handlers t/+write-handlers+} - :decoder-opts {:handlers t/+read-handlers+}})) - :middleware [ - ;; {:name "CORS Middleware" - ;; :wrap #(wrap-cors % - ;; :access-control-allow-origin [#".*"] - ;; :access-control-allow-methods [:get :put :post :delete] - ;; :access-control-allow-headers ["x-requested-with" - ;; "content-type" - ;; "authorization"])} - [wrap-session {:store (cookie-store {:key "a 16-byte secret"}) - :cookie-name "session" - :cookie-attrs {:same-site :lax - :http-only true}}] - parameters/parameters-middleware - api-middleware/normalize-params-middleware - ;; content-negotiation - muuntaja/format-negotiate-middleware - ;; encoding response body - muuntaja/format-response-middleware - ;; exception handling - api-errors/exception-middleware - ;; decoding request body - muuntaja/format-request-middleware - ;; validation - api-middleware/parameters-validation-middleware - ;; multipart - multipart/multipart-middleware]}})) + router-options)) (def app (ring/ring-handler routes (ring/create-default-handler))) diff --git a/backend/src/uxbox/api/middleware.clj b/backend/src/uxbox/api/middleware.clj index dc5f24414..63de3f70f 100644 --- a/backend/src/uxbox/api/middleware.clj +++ b/backend/src/uxbox/api/middleware.clj @@ -5,19 +5,21 @@ ;; Copyright (c) 2016-2019 Andrey Antukh (ns uxbox.api.middleware - (:require [reitit.core :as rc] - [struct.core :as st] + (:require [muuntaja.core :as m] [promesa.core :as p] + [reitit.core :as rc] + [reitit.ring.middleware.multipart :as multipart] + [reitit.ring.middleware.muuntaja :as muuntaja] + [reitit.ring.middleware.parameters :as parameters] + [ring.middleware.session :refer [wrap-session]] + [ring.middleware.session.cookie :refer [cookie-store]] + [struct.core :as st] + [uxbox.api.errors :as api-errors] [uxbox.util.data :refer [normalize-attrs]] - [uxbox.util.exceptions :as ex])) + [uxbox.util.exceptions :as ex] + [uxbox.util.transit :as t])) -;; (extend-protocol rc/Expand -;; clojure.lang.Var -;; (expand [this opts] -;; (merge (rc/expand (deref this) opts) -;; {::handler-metadata (meta this)}))) - -(defn transform-handler +(defn- transform-handler [handler] (fn [request respond raise] (try @@ -30,17 +32,7 @@ (catch Exception e (raise e))))) -(defn handler - [invar] - (let [metadata (meta invar) - hlrdata (-> metadata - (dissoc :arglist :line :column :file :ns) - (assoc :handler (transform-handler (var-get invar)) - :fullname (symbol (str (:ns metadata)) (str (:name metadata)))))] - (cond-> hlrdata - (:doc metadata) (assoc :description (:doc metadata))))) - -(def normalize-params-middleware +(def ^:private normalize-params-middleware {:name ::normalize-params-middleware :wrap (fn [handler] (letfn [(transform-request [request] @@ -58,9 +50,7 @@ (raise e))))))))}) -;; --- Validation - -(def parameters-validation-middleware +(def ^:private parameters-validation-middleware (letfn [(prepare [parameters] (reduce-kv (fn [acc key spec] @@ -81,21 +71,72 @@ (ex/raise :type :parameters-validation :code (:key spec) :context errors + :value (get req key) :message "Invalid data") - (assoc-in req [:parameters (:key spec)] result)))) - request parameters))] + request parameters)) + (compile [route opts] + (when-let [parameters (:parameters route)] + (let [parameters (prepare parameters)] + (fn [handler] + (fn + ([request] + (handler (validate request parameters))) + ([request respond raise] + (try + (handler (validate request parameters false) respond raise) + (catch Exception e + (raise e)))))))))] {:name ::parameters-validation-middleware - :compile (fn [route opts] - (when-let [parameters (:parameters route)] - (let [parameters (prepare parameters)] - (fn [handler] - (fn - ([request] - (handler (validate request parameters))) - ([request respond raise] - (try - (handler (validate request parameters false) respond raise) - (catch Exception e - (raise e)))))))))})) + :compile compile})) + +(def ^:private session-middleware + (let [options {:store (cookie-store {:key "a 16-byte secret"}) + :cookie-name "session" + :cookie-attrs {:same-site :lax :http-only true}}] + {:name ::session-middleware + :wrap #(wrap-session % options)})) + +;; (def ^:private cors-middleware +;; {:name ::cors-middleware +;; :wrap #(wrap-cors % +;; :access-control-allow-origin [#".*"] +;; :access-control-allow-methods [:get :put :post :delete] +;; :access-control-allow-headers ["x-requested-with" +;; "content-type" +;; "authorization"])}) + +(def ^:private muuntaja-instance + (m/create (update-in m/default-options [:formats "application/transit+json"] + merge {:encoder-opts {:handlers t/+write-handlers+} + :decoder-opts {:handlers t/+read-handlers+}}))) +(def router-options + {;;:reitit.middleware/transform dev/print-request-diffs + :data {:muuntaja muuntaja-instance + :middleware [session-middleware + parameters/parameters-middleware + normalize-params-middleware + ;; content-negotiation + muuntaja/format-negotiate-middleware + ;; encoding response body + muuntaja/format-response-middleware + ;; exception handling + api-errors/exception-middleware + ;; decoding request body + muuntaja/format-request-middleware + ;; validation + parameters-validation-middleware + ;; multipart + multipart/multipart-middleware]}}) + +(defn handler + [invar] + (let [metadata (meta invar) + hlrdata (-> metadata + (dissoc :arglist :line :column :file :ns) + (assoc :handler (transform-handler (var-get invar)) + :fullname (symbol (str (:ns metadata)) (str (:name metadata)))))] + (cond-> hlrdata + (:doc metadata) (assoc :description (:doc metadata))))) + diff --git a/backend/src/uxbox/api/pages.clj b/backend/src/uxbox/api/pages.clj index 3690c01d7..b5dda23ca 100644 --- a/backend/src/uxbox/api/pages.clj +++ b/backend/src/uxbox/api/pages.clj @@ -26,9 +26,9 @@ "Create page for a project" {:parameters {:body {:data [st/required] :metadata [st/required] - :project [st/required st/uuid-str] + :project [st/required st/uuid] :name [st/required st/string] - :id [st/uuid-str]}}} + :id [st/uuid]}}} [{:keys [user parameters]}] (let [data (get parameters :body) message (assoc data :user user :type :create-page)] @@ -42,10 +42,10 @@ {:parameters {:path {:id [st/required st/uuid-str]} :body {:data [st/required] :metadata [st/required] - :project [st/required st/uuid-str] + :project [st/required st/uuid] :name [st/required st/string] :version [st/required st/integer] - :id [st/uuid-str]}}} + :id [st/uuid]}}} [{:keys [user parameters]}] (let [id (get-in parameters [:path :id]) data (get parameters :body) @@ -56,9 +56,9 @@ (defn update-metadata "Update page metadata" {:parameters {:path {:id [st/required st/uuid-str]} - :body {:id [st/required st/uuid-str] + :body {:id [st/required st/uuid] :metadata [st/required] - :project [st/required st/uuid-str] + :project [st/required st/uuid] :name [st/required st/string]}}} [{:keys [user parameters]}] (let [id (get-in parameters [:path :id]) @@ -87,3 +87,17 @@ message (assoc data :id id :type :list-page-history :user user)] (->> (sv/query message) (p/map #(http/ok %))))) + +(defn update-history + {:parameters {:path {:id [st/required st/uuid-str] + :hid [st/required st/uuid-str]} + :body {:label [st/required st/string] + ::pinned [st/required st/boolean]}}} + [{:keys [user parameters]}] + (let [{:keys [id hid]} (get parameters :path) + message (assoc (get parameters :body) + :type :update-page-history + :id hid + :user user)] + (->> (sv/novelty message) + (p/map #(http/ok %)))))