forked from b-social/liberator-hal-events-resource
/
events_resource.clj
101 lines (90 loc) · 3.2 KB
/
events_resource.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
(ns liberator-hal-events-resource.events-resource
(:require
[halboy.resource :as hal]
[hype.core :as hype]
[liberator-mixin.core :refer [build-resource]]
[liberator-mixin.json.core :refer [with-json-mixin]]
[liberator-mixin.validation.core :refer [with-validation-mixin]]
[liberator-mixin.hypermedia.core :refer [with-hypermedia-mixin]]
[liberator-mixin.hal.core :refer [with-hal-mixin]]))
(defn with-unauthorised-handling
[]
{:handle-forbidden
(fn [_]
(hal/new-resource))})
(defn load-and-transform-events [events-loader-fn events-transformer-fn]
(let [events (events-loader-fn)
event-resources (map events-transformer-fn events)
event-links (map #(hal/get-link % :self) event-resources)]
[events event-resources event-links]))
(defn events-link-for [request routes query-params options]
{:href (hype/absolute-url-for request routes
(:route-key options :events)
{:query-params query-params})})
(defn self-link-for [request routes since page-size options]
(events-link-for request
routes
(merge
{:pick page-size}
(when-not (nil? since)
{:since since}))
options))
(defn next-link-for [request routes events page-size options]
(let [since (:id (last events))]
(events-link-for request
routes
{:since since
:pick page-size}
options)))
(defn add-next-link
[resource request routes events page-size options]
(if-not (empty? events)
(hal/add-link resource
:next
(next-link-for request routes events page-size options))
resource))
(defprotocol EventsLoader
(load-events [this parameters]))
(defn build-events-resource
([dependencies
default-page-size
events-loader
events-transformer-fn]
(build-events-resource dependencies
default-page-size
events-loader
events-transformer-fn
{}))
([dependencies
default-page-size
events-loader
events-transformer-fn
options]
(let [routes (:routes dependencies)]
(build-resource
(with-json-mixin dependencies)
(with-validation-mixin dependencies)
(with-hypermedia-mixin dependencies)
(with-hal-mixin dependencies)
(with-unauthorised-handling)
{:allowed-methods
[:get]
:handle-ok
(fn [{:keys [request]}]
(let [since (get-in request [:params :since] nil)
order (.toUpperCase (get-in request [:params :order] "ASC"))
page-size (get-in request [:params :pick] default-page-size)]
(let [[events event-resources event-links]
(load-and-transform-events
#(load-events events-loader
{:since since :pick page-size :order order})
#(events-transformer-fn dependencies request routes %))]
(->
(hal/new-resource)
(hal/add-links
{:self
(self-link-for request routes since page-size options)
:events
event-links})
(add-next-link request routes events page-size options)
(hal/add-resource :events event-resources)))))}))))