diff options
| author | eltrac <hi@eltr.ac> | 2026-10-07 17:04:04 +0800 |
|---|---|---|
| committer | eltrac <hi@eltr.ac> | 2026-10-07 17:04:04 +0800 |
| commit | e6ca4cbecff78a0f26086178c48e8fc66914ab86 (patch) | |
| tree | 489bd51e684a3972734aa5b79efef8413dc307bf /src | |
| parent | 89d5bd3a26619e30dcf8b7382432180a399d25c9 (diff) | |
handler: pluggable services in API routes/handlers
Diffstat (limited to 'src')
| -rw-r--r-- | src/weepinbell/webserver/facade.clj | 22 | ||||
| -rw-r--r-- | src/weepinbell/webserver/feed.clj | 2 | ||||
| -rw-r--r-- | src/weepinbell/webserver/handler.clj | 43 | ||||
| -rw-r--r-- | src/weepinbell/webserver/receiver.clj | 3 | ||||
| -rw-r--r-- | src/weepinbell/webserver/retriever.clj | 3 |
5 files changed, 48 insertions, 25 deletions
diff --git a/src/weepinbell/webserver/facade.clj b/src/weepinbell/webserver/facade.clj index ba9b8b0..23d5689 100644 --- a/src/weepinbell/webserver/facade.clj +++ b/src/weepinbell/webserver/facade.clj @@ -1,19 +1,33 @@ (ns weepinbell.webserver.facade (:require [org.httpkit.server :refer [run-server]] - [weepinbell.webserver.handler :refer [app]] [taoensso.timbre :as timbre] - [clojure.spec.alpha :as s])) + [clojure.spec.alpha :as s] + [weepinbell.webserver.handler :refer [app]] + ;; services + [weepinbell.webserver.receiver :as receiver] + [weepinbell.webserver.retriever :as retriever] + [weepinbell.webserver.feed :as feed])) (s/def ::server-meta (s/keys :req-un [::wmc ::store ::config])) +(defn make-services [] + {:post [#(s/valid? :weepinbell.webserver.handler/services %)]} + {:gen-feed feed/rss + :receive receiver/receive + :retrieve-by-domain retriever/by-domain + :retrieve-by-url retriever/by-url + :retrieve-by-id retriever/by-id + :retrieve-by-pair retriever/by-st-pair}) + (defn start-webserver "Starts web server. Returns a function that stops the server." [metadata] {:pre [(s/valid? ::server-meta metadata)] :post [fn?]} - (let [{:keys [wmc store config]} metadata + (let [{:keys [config]} metadata + api-meta (assoc metadata :services (make-services)) port (Integer/parseInt (or (:port config) (System/getenv "PORT") "3000"))] (timbre/info "starting web server, listening on" port) - (run-server (app wmc store config) {:port port}))) + (run-server (app api-meta) {:port port}))) diff --git a/src/weepinbell/webserver/feed.clj b/src/weepinbell/webserver/feed.clj index 12a39ec..7a78a9a 100644 --- a/src/weepinbell/webserver/feed.clj +++ b/src/weepinbell/webserver/feed.clj @@ -1,5 +1,5 @@ (ns weepinbell.webserver.feed - "Handler of route /feed/:domain. Generating RSS feed for each domain." + "Service generating RSS feed for each domain." (:require [clj-rss.core :as rss] [weepinbell.utils.url :refer [get-domain]] [weepinbell.utils.digest :refer [digest]]) diff --git a/src/weepinbell/webserver/handler.clj b/src/weepinbell/webserver/handler.clj index b6fac9e..b1d6990 100644 --- a/src/weepinbell/webserver/handler.clj +++ b/src/weepinbell/webserver/handler.clj @@ -1,20 +1,31 @@ (ns weepinbell.webserver.handler "Handler define routes and wrap responses. It pass request to other specific handlers. Other handlers are receiver, retriever and feed." - (:require [compojure.core :refer [routes POST GET context]] + (:require [clojure.spec.alpha :as s] + [compojure.core :refer [routes POST GET context]] [compojure.route :as route] [ring.middleware.defaults :refer [wrap-defaults api-defaults]] [ring.middleware.resource :refer [wrap-resource]] - [ring.middleware.json :refer [wrap-json-response]] - [weepinbell.webserver.receiver :refer [receive]] - [weepinbell.webserver.retriever :as retriever] - [weepinbell.webserver.feed :as feed])) + [ring.middleware.json :refer [wrap-json-response]])) + +(s/def ::services + (s/and (s/keys :req-un [::receive ::retrieve-by-url ::retrieve-by-domain + ::retrieve-by-id ::retrieve-by-pair ::gen-feed]) + #(every? fn? (vals %)))) +(s/def ::api-meta + (s/keys :req-un [::wmc ::store ::config ::services])) (defn- make-api "Receives webmention channel, storage vtable and config map. Returns a vector of compojure route handlers. Some may be nil." - [wmc storage config] - [;; receiver endpoint + [api-meta] + {:pre [(s/valid? ::api-meta api-meta)] + :post [sequential?]} + (let [{:keys [wmc store config services]} api-meta + {:keys [receive retrieve-by-url retrieve-by-domain + retrieve-by-id retrieve-by-pair + gen-feed]} services] + [;; receiver endpoint (POST (:endpoint config) [source target] (receive {:s source :t target} wmc config)) ;; query API routes @@ -22,21 +33,21 @@ ;; query webmention list (context "/mentions" [page microformats mftype] (GET "/" [url] - (retriever/by-url url page storage + (retrieve-by-url url page store {:microformats microformats :type mftype})) (GET "/:domain" [domain] - (retriever/by-domain domain page storage + (retrieve-by-domain domain page store {:microformats microformats :type mftype}))) ;; query one specific webmention (context "/mention" [microformats] - (GET "/:id" [id] (retriever/by-id id storage + (GET "/:id" [id] (retrieve-by-id id store {:microformats microformats})) - (GET "/" [source target] (retriever/by-st-pair source target storage + (GET "/" [source target] (retrieve-by-pair source target store {:microformats microformats})))) ;; RSS feed - (GET "/feed/:domain" [domain] (feed/rss domain storage config)) + (GET "/feed/:domain" [domain] (gen-feed domain store config)) ;; host proxied avatars (microformats photos) (route/files "/avatars/" {:root "data/avatars"}) ;; frontend @@ -44,7 +55,7 @@ (when (= (:source fe) :disk) (route/files "/" {:root (:dir fe)}))) ;; 404 - (route/not-found "Not Found")]) + (route/not-found "Not Found")])) (defn- make-handler "Receive a vector of handlers. Remove nil elements. @@ -55,11 +66,11 @@ (defn app "Receive webmention channel, storage vtable and config map. Returns an app handler." - [wmc storage config] - (when (= :clojure.spec.alpha/invalid storage) + [api-meta] + (when (= :clojure.spec.alpha/invalid (:store api-meta)) (println "Invalid storage. Check your database configuration or submit an issue.") (System/exit 1)) - (-> (make-api wmc storage config) + (-> (make-api api-meta) make-handler (wrap-resource "static") (wrap-defaults api-defaults) diff --git a/src/weepinbell/webserver/receiver.clj b/src/weepinbell/webserver/receiver.clj index 144f3db..9d14a10 100644 --- a/src/weepinbell/webserver/receiver.clj +++ b/src/weepinbell/webserver/receiver.clj @@ -1,6 +1,5 @@ (ns weepinbell.webserver.receiver - "Handler of route /endpoint or any other route the user configured. - Receiver receives Webmention request (a source and a target); verify the request; return error message if any; push Webmention into webbmention channel for processor to take." + "Service receiving Webmention request (a source and a target); verify the request; return error message if any; push Webmention into webbmention channel for processor to take." (:require [clojure.core.async :refer [put!]] [weepinbell.utils.url :refer [get-domain valid-http-url? normalize url=]] [weepinbell.utils.digest :refer [digest]])) diff --git a/src/weepinbell/webserver/retriever.clj b/src/weepinbell/webserver/retriever.clj index a8c175d..b597daf 100644 --- a/src/weepinbell/webserver/retriever.clj +++ b/src/weepinbell/webserver/retriever.clj @@ -1,6 +1,5 @@ (ns weepinbell.webserver.retriever - "Handler of routes /api/mention/:id, /api/mentions/... - Retriever gets webmention form storage and wraps it in a response." + "Service getting webmention form storage and wrapping it in a response." (:require [weepinbell.utils.url :refer [get-domain url=]] [weepinbell.microformats.reducer :refer [reduce-mf]])) |
