Coder Social home page Coder Social logo

polaris's Introduction

polaris

Requests guided by the constellations

Polaris

Routing defined by data, not macros.

Also, provides reverse routing for building urls from parameters!

Installation

Leiningen

[polaris "0.0.15"]

Usage

Polaris uses a data-driven routing defintion approach. Routes are given as a vector of route definitions. Every route definition has the following form:

["/path/to/match" :identifying-key handler-fn [optional-child-routes]]

Variables in paths can be specified with a :keyword:

["/path/with/:variable" :identifying-key handler-fn [optional-child-routes]]

Once you have a vector of route definitions, you can build your routes with polaris.core/build-routes:

(defn base-handler
  [request]
  {:status 200
   :body "This is the base"})

(defn sub-handler
  [request]
  {:status 200
   :body (str "We received " (-> request :params :leaf))})

(def route-definitions
  [["/base-path" :base base-handler
    [["/sub-path/:leaf" :sub sub-handler]]]])

(def routes (polaris.core/build-routes route-definitions))

Once you have some routes, you can match requests!

(def handler (polaris.core/router routes))
(handler {:uri "/base-path"}) ;; ---> {:status 200 :body "This is the base"}

Child routes inherit their path from their parent, so for the above routes the following request would work:

(handler {:uri "/base-path/sub-path/yellow"}) ;; ---> {:status 200 :body "We received yellow"}

Route matching works with or without following slashes:

(handler {:uri "/base-path/sub-path/chartreuse/"}) ;; ---> {:status 200 :body "We received chartreuse"}

Handlers can be scoped to different request methods:

(defn get-handler
  [request]
  {:status 200
   :body "The method defaults to GET"})

(defn post-handler
  [request]
  {:status 200
   :body "This is a POST"})

(defn delete-handler
  [request]
  {:status 200
   :body "DELETED!!"})

(def route-definitions
  [["/method-sensitive" :base {:GET base-handler :POST post-handler :DELETE delete-handler}]])

(def routes (polaris.core/build-routes route-definitions))
(def handler (polaris.core/router routes))

(handler {:uri "/method-sensitive"}) ;; ---> {:status 200 :body "The method defaults to GET"}
(handler {:uri "/method-sensitive" :request-method :post}) ;; --> {:status 200 :body "This is a POST"}
(handler {:uri "/method-sensitive" :request-method :delete}) ;; --> {:status 200 :body "DELETED!!"}

Subtree Middleware

You can define middleware for a path and all subpaths relative to that path (the subtree). Because middleware forms a stack around the original handler, there are two different ways to add it to the three: float and sink. If you float the middleware, it will compose itself at the outermost layer of middleware currently defined for that handler. Since each path can inherit middleware from paths above it, this stack can grow arbitrarily deep. If you sink the middleware, it will go to the bottom of this stack (ie. run right before the handler). If deeper down another middleware is sunk, it will go inside even this one.

(defn ocean-rock
  [request]
  {:status 200
   :body "An ocean rock"})

(defn sea-floor
  [request]
  {:status 200
   :body "A sandy sea floor"})

(defn anemone
  [app]
  (fn [request]
    (update-in (app request) [:body] #(str % " covered in anemone"))))

(defn boat
  [app]
  (fn [request]
    (update-in (app request) [:body] #(str % " underneath a small boat"))))

(def sea-routes
  [["/ocean" :ocean {:ALL ocean-rock :sink anemone :float boat}
    [["/floor" :floor sea-floor]]]])

(def routes (polaris.core/build-routes sea-routes))
(def handler (polaris.core/router routes))

(handler {:uri "/ocean"}) ;; ---> {:status 200 :body "An ocean rock covered in anemone underneath a small boat"}
(handler {:uri "/ocean/floor"}) ;; ---> {:status 200 :body "A sandy sea floor covered in anemone underneath a small boat"}

Reverse Routing

Polaris supports reverse routing, which means you can reconstruct a url based on the route's identifying key and a map of values to substitute into any variable path elements.

(def route-definitions
  [["/path/:with/:lots/:of/:variables" :demo (fn [request] "WHAT")]])

(def routes (polaris.core/build-routes route-definitions))
(polarise.core/reverse-route routes :demo {:with "now" :lots "formed" :of "from" :variables "map"})
;; --> "/path/now/formed/from/map"   !!

License

Copyright © 2013 Ryan Spangler

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

polaris's People

Contributors

frozenlock avatar malloc47 avatar prismofeverything avatar ralfonso avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.