(Janus was a two-faced Roman god who looked forward to the future and backwards to the past. His name gives us the name of the month January
)
A Clojure routing library. This is my second initiative on this front -the first as a collaborator on the wire
library. Inspiration has been taken from:
The interpretation of "URL"s is rife with misunderstandings, competing standards and imcompatible interpretations. In the context of janus, a URI is the name by which a local resource is referenced on the web.
The way I see it, there are two jobs for a router
format
strings.These are the core functions of a "pure" routing engine and they should be powerful and generally uncompromised by secondary concerns.
/
-separated and url-encoded segments.See janus.route and janus.ring namespaces for usage notes.
The canonical format for a route is a recursive sequence of two elements, the second of which is a sequence of three elements:
[identifiable [as-segment dispatchable routes]]
The outer sequence can be viewed as a pair, and is satisfied by a Clojure map entry. In fact, maps are the preferred way of representing a collection of routes:
{identifiable1 [as-segment1 dispatchable1 routes1]
identifiable2 [as-segment2 dispatchable2 routes2]
...
identifiableN [as-segmentN dispatchableN routesN]}
Only when the identification of route segments is not guaranteed to be unique does the order of routes become meaningful. At that point, routes can be represented by a sequence of pairs:
[[identifiable1 [as-segment1 dispatchable1 routes1]
[identifiable2 [as-segment2 dispatchable2 routes2]
...
[identifiableN [as-segmentN dispatchableN routesN]]
Routes are organized as a tree: there is one root route and all child routes have exactly one parent.
The elements of a route are:
identifiable
is any instance of clojure.lang.Named
. This includes keywords and symbols. Keywords should be used when the matching of the route yields useful information. Symbols should be used for "constant" routes.
as-segment
is anything satisfying janus.route.AsSegment
, which includes strings, keywords, regexes, functions and others. The role of as-segment
is twofold: to match inbound route segements and to generate outbound route segements. The semantics of each are as follows:
javal.lang.String
matches itself only, generates itself always.
clojure.lang.Keyword
matches its name only, generates its name always.
java.util.regex.Pattern
FIXME: Document
clojure.lang.PersistentVector
FIXME: Document
clojure.lang.Fn
FIXME: Document
dispatchable
is anything satisfying janus.route.Dispatchable
, which includes functions, vars and instances of clojure.lang.Named
. FIXME: Document better, why is protocol not enforced specifically during normalization?
routes
is a recursive seqable collection of child routes.
While the canonical format for routes is useful for understanding the full capabilities of routing in janus, there are many abbreviated representations that are acceptable. There is no run-time performance penalty for expressing routes in any abbreviated format.
Only the identifiable
is required to represent a route. If the second element of the pair is missing or nil, default values are assigned based on the identifiable. For example:
[:root nil] => [:root [nil :root {}]]
[:root] => [:root [nil :root {}]]
Of course suppressing the second element is not possible when using a map to represent a sequence of routes.
Copyright © 2017 Chris Hapgood
Distributed under the Eclipse Public License version 1.0.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close