Skip to content

Commit

Permalink
adds routing examples
Browse files Browse the repository at this point in the history
  • Loading branch information
fardog committed Dec 29, 2015
1 parent b30e51c commit 3a73d96
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 0 deletions.
128 changes: 128 additions & 0 deletions docs/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,126 @@ Now you'll see a number of things, including your own `returning handler` debug
message. Running frock in debug mode can be very helpful when you're developing
your plugins.

## Routing

frock's internal routing is based on [commuter][], which is a wrapper for
[routes][] that understands sub-routes; that is, it's possible to mount new
sub-routers under a parent router, but the sub-routers don't need any special
knowlege of the parent to work correctly. It's this feature that makes writing
routes in frock much simpler and more re-usable.

If you're looking for any specific information on how to do route matching,
looking at [routes][] documentation is recommended; it has a complete list of
features that the route pattern matching supports.

It's important to note however: frock doesn't _require_ you to use its internal
router in your plugins—you're free to implement whatever router you see fit, but
the internal router is available for you to use (and will probably be the most
pleasant and simple to implement).

Although frock uses [commuter][], it's best to use the router factory that is
provided on the [frock-singleton][]; this ensures that your version of the
package matches frock's, so there are no bugs and incompatibilities between
versions—frock follows semver closely, and will not introduce a newly
incompatible version of commuter without a major version bump to frock.

The following routing examples are available:

### Routing in the frockfile

The frockfile uses [routes][] pattern-matching to define which handler should
take care of a particular request, as well as matching against the HTTP method
that the request was made with. The
[routing in the frockfile example][frockfile-routing] shows how to set up
multiple routes in your frockfile, as well as a fallback route to handle all
other requests.

In this [example][frockfile-routing] you'll see that the `respond-with-message`
plugin simply responds to any request with the message that was configured for
it in the options hash.

### Sub-routes in your plugins

The [sub-routes][] example shows you how to create a plugin that is mounted
under a path in your frockfile, and handle all requests in the plugin as though
it were the top-level router. This example is the most common implementation
pattern for a frock plugin, and should show you how to handle common cases
using frock's router.

In the [example][sub-routes], we mount a module that responds to an index page,
and routes `/one` and `/two` under two different mout points. In your browser,
visit `http://localhost:8080/mount-a/` and `http://localhost:8080/mount-b/`;
you'll see the index page for each. Then under each, visit `/one` and `/two`;
you'll see those pages. Note that the plugin has no knowledge of where its
mounted; it simply handles the routes as though it were the top-level router.

In that example, any route other than the ones above will 404, since no
catch-all route was defined.

### Capturing URL Parameters

The [url-parameters][] example shows how you can capture a parameter in your
URLs as defined in your frockfile or in a plugin route. A route parameter is as
follows:

- `/people/:id`, would match things like `/people/1` or `/people/miki`
- `/people/:name/family` would match things like `/people/dave/family` and
`/people/miki/family`
- You can also match multiples like `/people/:name/:item`, which would match
`/people/miki/games` and `/people/miki/documents`

When you define these sorts of patterns, the captures parameters will be
available on the `request.params` hash; so for the example
`/people/:name/:item` matching `/people/miki/games` would have a `req.params`
object as follows:

```json
{
"name": "miki",
"item": "games"
}
```

You can access these in your routes as necessary.

The [example][url-parameters] shows how you can use this in your plugins.

**Note:** if you attempt to capture a identically named parameter in a route
and then again in a sub-route, your sub-route's parameter will overwrite any
earlier routes. The latest-defined parameter always takes precedence.

## Middlewares

In lieu of an in-repo example, there is a simple [delay-middleware][] available;
its [code][delay-github] is a straightforward example of how to write
middlewares. You would use this in your frockfile as follows:

```json
{
"servers": [
{
"port": 8080,
"routes": [
{
"path": "/api",
"methods": ["GET"],
"handler": "./some-handler",
"middleware": [
{
"handler": "frock-middleware-delay",
"options": {
"min": 1000,
"max": 1500
}
}
]
}
]
}
]
}
```

## Transpiled Modules, ES2015

frock can support compiling/transpiling of modules, given the appropriate
Expand Down Expand Up @@ -135,3 +255,11 @@ in your projects.
[es2015-example]: ./es2015
[babel]: https://babeljs.io
[db-example]: ./db
[frockfile-routing]: ./routing-in-the-frockfile
[frock-singleton]: ../api.md
[commuter]: https://www.npmjs.com/packages/commuter
[routes]: https://www.npmjs.com/packages/routes
[sub-routes]: ./routing-sub-routes
[url-parameters]: ./routing-url-parameters
[delay-middleware]: https://www.npmjs.com/packages/frock-middleware-delay
[delay-github]: https://github.com/urbanairship/frock-middleware-delay
33 changes: 33 additions & 0 deletions docs/examples/routing-in-the-frockfile/frockfile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"servers": [
{
"port": 8080,
"routes": [
{
"path": "/api",
"methods": ["GET"],
"handler": "./respond-with-message",
"options": {
"message": "GET at /api"
}
},
{
"path": "/api",
"methods": ["POST"],
"handler": "./respond-with-message",
"options": {
"message": "POST at /api"
}
},
{
"path": "*",
"methods": "any",
"handler": "./respond-with-message",
"options": {
"message": "any other request"
}
}
]
}
]
}
15 changes: 15 additions & 0 deletions docs/examples/routing-in-the-frockfile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "frock-example-routing-in-the-frockfile",
"version": "1.0.0",
"description": "frock example showing routing in the frockfile",
"main": "respond-with-message.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"frock": "frock"
},
"author": "Urban Airship <web-team@urbanairship.com>",
"license": "Apache-2.0",
"devDependencies": {
"frock": "^1.0.1"
}
}
13 changes: 13 additions & 0 deletions docs/examples/routing-in-the-frockfile/respond-with-message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = createPlugin

function createPlugin (frock, logger, _options) {
var options = _options || {}
var message = options.message || 'no message provided'

return handler

function handler (req, res) {
res.setHeader('content-type', 'text/plain')
res.end(message)
}
}
19 changes: 19 additions & 0 deletions docs/examples/routing-sub-routes/frockfile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"servers": [
{
"port": 8080,
"routes": [
{
"path": "/mount-a/*",
"methods": ["GET"],
"handler": "./index-one-two"
},
{
"path": "/mount-b/*",
"methods": ["GET"],
"handler": "./index-one-two"
}
]
}
]
}
27 changes: 27 additions & 0 deletions docs/examples/routing-sub-routes/index-one-two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = createPlugin

function createPlugin (frock, logger, options) {
var router = frock.router(defaultRoute)

router.get('one', one)
router.get('two', two)
router.get('^$', index)

return router

function one (req, res) {
res.end('one!')
}

function two (req, res) {
res.end('two!')
}

function index (req, res) {
res.end('index!')
}
}

function defaultRoute (req, res) {
res.e404('no route configured')
}
15 changes: 15 additions & 0 deletions docs/examples/routing-sub-routes/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "frock-example-routing-sub-routes",
"version": "1.0.0",
"description": "frock example showing routing in sub-routes",
"main": "index-one-two.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"frock": "frock"
},
"author": "Urban Airship <web-team@urbanairship.com>",
"license": "Apache-2.0",
"devDependencies": {
"frock": "^1.0.1"
}
}

0 comments on commit 3a73d96

Please sign in to comment.