Ring middleware for the Turnstile rate limiting service
- Note: Version 0.1.1 is missing commit information–it corresponds to this commit.
Use wrap-rate-limit
to create an instance of the middleware, wrap your handler with it:
(require '[ring.middleware.turnstile
:refer [wrap-rate-limit ip-limit header-limit]]
'[ring.util.response :refer [response]])
(def app (-> your-routes
(wrap-rate-limit {:redis-conf {}
:key-prefix "your-api"
:limit-fns [(ip-limit 200)
(header-limit 300 "x-role" "ROLE")]))
;; 200 requests per hour per IP address
;; 300 requests per hour per value of the header `x-role`
If you want to do some specific operations when a call is rate limited, you can define your own rate limit handler:
(require '[ring.middleware.turnstile :refer [wrap-rate-limit ip-limit]]
'[ring.util.response :refer [response]])
(def app (-> your-routes
(wrap-rate-limit {:redis-conf {}
:key-prefix "your-api"
:limit-fns [(ip-limit 200)]
:rate-limit-handler
(fn [request next-slot-in-sec limit]
{:status 429
:body (format "Too many requests, try later in %d s"
next-slot-in-sec)})}))
You can create your own limit
(require '[ring.middleware.turnstile :refer [wrap-rate-limit ip-limit]]
'[ring.util.response :refer [response]])
(def custom-limit
[request]
(when-let [role (get-in request [:jwt "role"])
ip-limit-fn (ip-limit 100)]
(cond-> (ip-limit-fn request)
(= "admin" role) (assoc :nb-request-per-hour 200))))
(def app (-> your-routes
(wrap-rate-limit {:redis-conf {}
:key-prefix "your-api"
:limits [custom-limit]))
;; 200 requests per hour per IP for amdin users
;; 100 requests per hour for the others
The limit fn must return a hash map with the following keys:
Keyword | Description |
:nb-request-per-hour | The number of request per hour limit |
:rate-limit-key | The rate limit key to group requests |
:name-in-headers | Used in the rate limit headers to identify a rate limit. (templates: X-RateLimit-%s-Limit , X-RateLimit-%s-Limit ). Field names in HTTP headers are case-insensitive and are composed by any char except control chars or separators |
or
nil
if the request is not rate limited.
Copyright © 2018 Cisco Systems Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.