@websdk/rhumb
v0.4.0
Published
URL routing in js
Downloads
15
Readme
Rhumb
Rhumb is a highly efficient and flexible router.
Given a URI – where the constituent parts may be fixed or variable – Rhumb will unambiguously and with negligable overhead find a matching function, then apply it with whatever parameters might have been extracted from the URI.
Bells and Whistles
- automatic path precedence
- ambiguity detection
- variables parts
- partially variable parts
- optional parts
- parameter parsing
- interpolate params to produce paths
Basic Usage
Rhumb allows you to map paths to functions
rhumb.add("/happy/shoes", function(){
return shoes
})
If those paths contain variable parts, rhumb will grab them for you
rhumb.add("/happy/shoes/{color}", function(params){
return shoes.inColor(params.color)
})
Whatever you return in the callback will to handed back to the caller of match
redShoes = rhumb.match("/happy/shoes/red")
When you need to create a URI from a set of params, the interpolate
function can be used
redShoesUri = rhumb.interpolate("/happy/shoes/{color}", { color: "red" })
Route Syntax
fixed paths
Fixed paths are the most simple
rhumb.add("/latest/potatoes")
will match /latest/potatoes
only
variable parts
Use variable parts in your path to allow a range of options
rhumb.add("/potatoes/{variety}")
This route will match when anything is provided as a variety e.g.
- /potatoes/osprey
- /potatoes/saxon
- /potatoes/marabel
- /potatoes/321
- /potatoes/chips
A variety must be provided, so /potatoes
alone will not match
Paths with variable parts generate a params
object which is passed to the callback
rhumb.add("/potatoes/{variety}", function(params){
console.log(params.variety)
})
rhumb.match("/potatoes/marabel")
// > "marabel"
partially variable parts
Partially variable parts allow you to capture more than one variable from a single segment of a URL.
If you wanted to capture a date in a url like /news-from/tue-march-1900
you could do so using partial parts.
rhumb.add("/news-from/{day}-{month}-{year}", function(params){
console.log(
params.day
, params.month
, params.year
)
})
optional parts
Optional parts, well, are optional
rhumb.add("/stories(/{name})")
The above route matches for /stories
and for /stories/anything
Optionals can be nested e.g.
rhumb.add("/stories(/{author}(/{genre}))")
Will match
/stories
/stories/bob
/stories/sarah/scary
Have fun!
Parameter Interpolation
Rhumb allows you to take a route and a set of params and produce a path that can be matched against a route.
fixed paths
When you give .interpolate(...)
a route without any declared variables or partial variable parts, then a valid path will be returned and you will typically not see any changes:
rhumb.interpolate("/stories", {})
// returns "/stories"
rhumb.interpolate("/stories?sortBy=publishedDate", {})
// returns "/stories?sortBy=publishedDate"
When the route you supplied is not a valid path, Rhumb will step in and escape some of the characters, so that a valid path can be produced.
If your route has empty parts, then some of the slash characters will be encoded to %2F
:
rhumb.interpolate('//sarah/scary', {})
// returns "/%2Fsarah/scary"
rhumb.interpolate('stories//scary', {})
// returns "stories%2F/scary"
variable parts
When variables are present, Rhumb will interpolate the variables with the params you supply:
rhumb.interpolate("/potatoes/{variety}", { variety: "marabel" })
// returns "/potatoes/marabel"
rhumb.interpolate("/shoes/{color}/{size}", { color: "red", size: "6" })
// returns "/shoes/red/6"
For interpolation to produce a valid path, it will throw an error when a required variable is absent, ""
, null
or undefined
:
rhumb.interpolate("/potatoes/{variety}", {})
// throws 'Invalid parameter: "variety" is missing'
rhumb.interpolate("/shoes/{color}/{size}", { color: "red", size: null })
// throws 'Invalid parameter: "size" is null'
To mark a variable part as not-required, it has to be wrapped in an optional path, as shown later.
partially variable parts
Like variables, Rhumb will interpolate partially variable parts when they are defined and not empty in the supplied params:
rhumb.interpolate("/orders/{days}-days-ago", { days: "40" })
// returns "/orders/40-days-ago"
rhumb.interpolate("/author/{forename}-{surname}", { forename: "susan", surname: "smith" })
// returns "/author/susan-smith"
It will also throw an error when a required partial variable is absent, ""
, null
or undefined
:
rhumb.interpolate("/orders/{days}-days-ago", { days: "" })
// throws 'Invalid parameter: "days" is empty'
rhumb.interpolate("/author/{forename}-{surname}", { forename: "susan", surname: undefined })
// throws 'Invalid parameter: "surname" is undefined'
To mark a partially variable part as not-required, it has to be wrapped in an optional path, as shown later.
optional parts
Rhumb is greedy with how it handles optional paths when interpolating, so expect optional parts to be included whenever possible.
rhumb.interpolate("/stories(/bob)", {})
// returns "/stories/bob"
rhumb.interpolate("/stories(/sarah(/scary))", {})
// returns "/stories/sarah/scary"
When variables or partially variables in optional parts are absent, ""
, null
or undefined
then no error is thrown and the optional part is dropped.
rhumb.interpolate("/stories(/by-{name})", {})
// returns "/stories"
rhumb.interpolate("/stories(/{author}(/{genre}))", { author: "sarah", genre: "" })
// returns "/stories/sarah"
Found an issue, or want to contribute?
If you find an issue, want to start a discussion on something related to this project, or have suggestions on how to improve it? Please create an issue!
See an error and want to fix it? Want to add a file or otherwise make some changes? All contributions are welcome! Please refer to the contribution guidelines for more information.
License
Please refer to the license for more information on licensing and copyright information.