/clj-rapid

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

clj-rapid

Build Status codecov Clojars Project

An simple routing library for Clojure, inspired by Python's Fast API and Rust Axum's route definitions.

[clj-rapid "0.2.0"]

Usage

Route Definitions

A function using a implicit path derived from the fn name:

;; Defines GET /ping
(defn ^:get ping []
    "up & runnig")

Define request handlers annotating your functions with HTTP methods : ^:get, ^:post, ^:put , ^:patch, ^:delete, ^:options

With explicit path:

(defn ^{:get "/posts"} get-posts []
    [{:id 1 :title "post 1"}])

With path parameters:

(defn ^{:get "/posts/:id"} get-post [id]
    ;; (get-post-by-id id)
    )

With parameter de-structuring:

(defn ^{:get "/posts"} get-posts [^:param offset ^:param limit]
    ;; (get-posts offset limit)
    )

You can annotate your function arguments with any of the following keywords: :body, :form, :form*, :query, :query*, :path, :param, :param*, :cookie, :request, :body

  • Use wildcard keywords: :param*, :query*, :form* to capture the full set of parameters of the given type.

With body payload:

(defn ^{:post "/posts"} new-post [^:body post]
    ;;(create-post post)
    )

With spec validation:

;; ...
(s/def ::article (s/keys :req-un [::title ::content]))

(defn ^{:post "/articles"} new-article [^{:body ::article} post]
    ;;(create-post post)
    )

If the parameter doesn't conform to the given specs, the handler returns a bad request (HTTP 400) response.

;; ...
(s/def ::search-params (s/keys :req-un [::limit ::offset]))

(defn ^{:get "/posts"} get-posts [^{:param* ::search-params} params]
    ;;(create-post post)
    )

With known type coercion/validation:

(defn ^{:get "/posts"} get-posts
    "retrieves up to `limit` number of posts starting in the given `offset`"
    [^{:param int} offset
    ^{:param int} limit]
    ;; (get-posts offset limit)
    )

With defaults

(defn ^{:get "/posts"} get-posts
    "retrieves up to `limit` number of posts starting in the given `offset`"
    [^{:param int :default 0} offset
    ^{:param int :default 10} limit]
    ;; (get-posts offset limit)
    )

Converting to Ring Handler

Creating a handler from all router functions in a namespace:

(def current-ns *ns*)

(handler current-ns)

Creating a handler from a list of router functions

(handler [#'get-posts #'new-post])

Composing handlers:

(handler  ["/" (handler fn1 fn2)]
    ["/api" (handler api-ns)]
    ["/static" (static-handler)])

License

Copyright © 2018 FIXME

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.