From 6a6ead0d63c7dda34fc16a6bc17d9db0c20d6370 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 11 May 2020 08:07:37 +0200 Subject: [PATCH] :sparkles: Minor improvement of http client api. Make it more compatible to be executed in worker. --- frontend/src/uxbox/main/repo.cljs | 69 ++++----------------------- frontend/src/uxbox/util/http.cljs | 10 ++-- frontend/src/uxbox/util/http_api.cljs | 56 ++++++++++++++++++++++ 3 files changed, 72 insertions(+), 63 deletions(-) create mode 100644 frontend/src/uxbox/util/http_api.cljs diff --git a/frontend/src/uxbox/main/repo.cljs b/frontend/src/uxbox/main/repo.cljs index 8576c028c..e6702eef2 100644 --- a/frontend/src/uxbox/main/repo.cljs +++ b/frontend/src/uxbox/main/repo.cljs @@ -2,64 +2,17 @@ ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; -;; Copyright (c) 2019 Andrey Antukh +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL (ns uxbox.main.repo (:require [beicon.core :as rx] [cuerdas.core :as str] [uxbox.config :refer [url]] - [uxbox.util.http :as http] - [uxbox.util.storage :refer [storage]] - [uxbox.util.transit :as t]) - (:import [goog.Uri QueryData])) - -;; --- Low Level API - -(defn- conditional-decode - [{:keys [body headers] :as response}] - (let [contentype (get headers "content-type")] - (if (str/starts-with? contentype "application/transit+json") - (assoc response :body (t/decode body)) - response))) - -(defn- handle-http-status - [{:keys [body status] :as response}] - (if (http/success? response) - (rx/of {:status status :payload body}) - (rx/throw {:status status :payload body}))) - -(def ^:private +headers+ - {"content-type" "application/transit+json"}) - -(defn- encode-query - [params] - (let [data (QueryData.)] - (.extend data (clj->js params)) - (.toString data))) - -(defn impl-send - [{:keys [body headers auth method query url response-type] - :or {auth true response-type :text}}] - (let [headers (merge {"Accept" "application/transit+json,*/*"} - (when (map? body) +headers+) - headers) - request {:method method - :url url - :headers headers - :query query - :body (if (map? body) (t/encode body) body)} - options {:response-type response-type - :credentials? true}] - (http/send! request options))) - -(defn send! - [request] - (->> (impl-send request) - (rx/map conditional-decode) - (rx/mapcat handle-http-status))) - -;; --- High Level API + [uxbox.util.http-api :as http])) (defn- handle-response [response] @@ -77,15 +30,13 @@ (defn send-query! [id params] (let [url (str url "/api/w/query/" (name id))] - (->> (impl-send {:method :get :url url :query params}) - (rx/map conditional-decode) + (->> (http/send! {:method :get :url url :query params}) (rx/mapcat handle-response)))) (defn send-mutation! [id params] (let [url (str url "/api/w/mutation/" (name id))] - (->> (impl-send {:method :post :url url :body params}) - (rx/map conditional-decode) + (->> (http/send! {:method :post :url url :body params}) (rx/mapcat handle-response)))) (defn- dispatch @@ -138,15 +89,13 @@ (defmethod mutation :login [id params] (let [url (str url "/api/login")] - (->> (impl-send {:method :post :url url :body params}) - (rx/map conditional-decode) + (->> (http/send! {:method :post :url url :body params}) (rx/mapcat handle-response)))) (defmethod mutation :logout [id params] (let [url (str url "/api/logout")] - (->> (impl-send {:method :post :url url :body params :auth false}) - (rx/map conditional-decode) + (->> (http/send! {:method :post :url url :body params :auth false}) (rx/mapcat handle-response)))) (def client-error? http/client-error?) diff --git a/frontend/src/uxbox/util/http.cljs b/frontend/src/uxbox/util/http.cljs index 54508d729..36cac6e84 100644 --- a/frontend/src/uxbox/util/http.cljs +++ b/frontend/src/uxbox/util/http.cljs @@ -2,15 +2,20 @@ ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; -;; Copyright (c) 2016 Andrey Antukh +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL (ns uxbox.util.http "A http client with rx streams interface." (:refer-clojure :exclude [get]) (:require + [cljs.core :as c] [beicon.core :as rx] + [clojure.string :as str] [goog.events :as events] - [clojure.string :as str]) + [uxbox.util.transit :as t]) (:import [goog.net ErrorCode EventType] [goog.net.XhrIo ResponseType] @@ -78,7 +83,6 @@ (letfn [(on-complete [event] (let [type (translate-error-code (.getLastErrorCode xhr)) status (.getStatus xhr)] - ;; (prn "on-complete" type method url) (if (pos? status) (sink (rx/end {:status status diff --git a/frontend/src/uxbox/util/http_api.cljs b/frontend/src/uxbox/util/http_api.cljs new file mode 100644 index 000000000..72499545e --- /dev/null +++ b/frontend/src/uxbox/util/http_api.cljs @@ -0,0 +1,56 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL + +(ns uxbox.util.http-api + "A specific customizations of http client for api access." + (:require + [beicon.core :as rx] + [cuerdas.core :as str] + [uxbox.util.http :as http] + [uxbox.util.transit :as t])) + +(defn- conditional-decode + [{:keys [body headers] :as response}] + (let [contentype (get headers "content-type")] + (if (str/starts-with? contentype "application/transit+json") + (assoc response :body (t/decode body)) + response))) + +(defn- handle-http-status + [{:keys [body status] :as response}] + (if (http/success? response) + (rx/of {:status status :payload body}) + (rx/throw {:status status :payload body}))) + +(def ^:private default-headers + {"content-type" "application/transit+json"}) + +(defn- impl-send + [{:keys [body headers auth method query url response-type] + :or {auth true response-type :text}}] + (let [headers (merge {"Accept" "application/transit+json,*/*"} + default-headers + headers) + request {:method method + :url url + :headers headers + :query query + :body (when (not= :get method) (t/encode body))} + options {:response-type response-type + :credentials? auth}] + (http/send! request options))) + +(defn send! + [request] + (->> (impl-send request) + (rx/map conditional-decode))) + +(def success? http/success?) +(def client-error? http/client-error?) +(def server-error? http/server-error?)