Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

renaming things

  • Loading branch information...
commit 8a8df6d458f6a4bd6bd7c2a549e43680f06917b8 1 parent 49d70bf
@basti1302 authored
View
61 README.md
@@ -26,20 +26,19 @@ Table of Contents
* [Node.js](#nodejs)
* [Browser](#browser)
* [Documentation by Example](#documentation-by-example)
- * [Walking Along Links](#walking-along-links)
+ * [Following Links](#following-links)
* [Get Full HTTP Response](#more-control-receive-the-full-http-response)
* [Pass Links as Array](#pass-a-link-array)
* [POST, PUT, DELETE and PATCH](#post-put-delete-and-patch)
* [Error Handling](#error-handling)
* [JSONPath](#jsonpath)
* [URI Templates](#uri-templates)
- * [Headers and Authentication](#headers-http-basicauth-oauth-and-whatnot)
+ * [Headers and Authentication](#headers-http-basic-auth-oauth-and-whatnot)
* [HAL](#hal---hypermedia-application-language)
* [Features From the Future](#features-from-the-future)
* [Caching](#caching)
* [Customizing Traverson](#customizing-traverson)
* [Enabling/Disabling Features](#enablingdisabling-features)
- * [Overriding](#overriding-parts-of-traversons-walk-behaviour)
* [Other Media Types](#other-media-types-besides-json)
Installation
@@ -66,7 +65,7 @@ Documentation by Example
This section shows how to use Traverson's features with small examples.
-### Walking Along Links
+### Following Links
The most basic thing you can do with traverson is to let it start at the root URI of an API, follow some links and pass the resource that is found at the end of this journey back to you. Here's how:
@@ -74,12 +73,12 @@ The most basic thing you can do with traverson is to let it start at the root UR
var api = traverson.json.from('http://api.io')
api.newRequest()
- .walk('link_to', 'resource')
+ .follow('link_to', 'resource')
.getResource(function(error, document) {
if (error) {
console.error('No luck :-)')
} else {
- console.log('We have walked the path and reached our destination.')
+ console.log('We have followed the path and reached our destination.')
console.log(JSON.stringify(document))
}
})
@@ -95,7 +94,7 @@ Given this call, Traverson first fetches `http://api.io` (because that's what we
(To make the examples easier to read, we note the URI corresponding to the document above each document. The URI is of course not part of the JSON response body.)
-After receiving the document from the start URI, Traverson starts to follow the provided via the `walk` method. Since the first link is `link_to`, it looks for a property with this name in the JSON response. In this case, this yields the next URI to access: `http://api.io/follow/me`. Traverson will fetch the document from there now. Let's assume this document looks like to this:
+After receiving the document from the start URI, Traverson starts to follow the links provided via the `follow` method. Since the first link is `link_to`, it looks for a property with this name in the JSON response. In this case, this yields the next URI to access: `http://api.io/follow/me`. Traverson will fetch the document from there now. Let's assume this document looks like to this:
https://api.io/follow/me
{
@@ -104,7 +103,7 @@ After receiving the document from the start URI, Traverson starts to follow the
"resource": "http://api.io/follow/me/to/the/stars"
}
-Now, since the next link given to `walk` is `resource`, Traverson will look for the property `resource`. Finding that, Traverson will finally fetch the JSON document from `http://api.io/follow/me/to/the/stars`:
+Now, since the next link given to `follow` is `resource`, Traverson will look for the property `resource`. Finding that, Traverson will finally fetch the JSON document from `http://api.io/follow/me/to/the/stars`:
http://api.io/follow/me/to/the/stars
{
@@ -113,22 +112,22 @@ Now, since the next link given to `walk` is `resource`, Traverson will look for
...
}
-Because the list of links given to `walk` is exhausted now (`resource` was the last element), this document will be passed into to the callback you provided when calling the `getResource` method. Coming back to the example from the top, the output would be
+Because the list of links given to `follow` is exhausted now (`resource` was the last element), this document will be passed into to the callback you provided when calling the `getResource` method. Coming back to the example from the top, the output would be
- We have walked the path and reached the final resource.
+ We have followed the path and reached the final resource.
{ "the_document": "that we really wanted to have", "with": "lots of interesting and valuable content", ... }
### More Control: Receive the Full HTTP Response
-The example above chained the `getResource` method to the `walk` method. For this method, Traverson will parse the JSON from the last HTTP response and pass the resulting JavaScript object to your callback. In certain situations you might want more control and would like to receive the full HTTP response object instead of the body, already parsed to an object. This is what the `get` method is for:
+The example above chained the `getResource` method to the `follow` method. For this method, Traverson will parse the JSON from the last HTTP response and pass the resulting JavaScript object to your callback. In certain situations you might want more control and would like to receive the full HTTP response object instead of the body, already parsed to an object. This is what the `get` method is for:
api.newRequest()
- .walk('link_to', 'resource')
+ .follow('link_to', 'resource')
.get(function(error, response) {
if (error) {
console.error('No luck :-)')
} else {
- console.log('We have walked the path and reached our destination.')
+ console.log('We have followed the path and reached our destination.')
console.log('HTTP status code: ' + response.statusCode)
console.log('Response Body: ' + response.body)
}
@@ -136,19 +135,19 @@ The example above chained the `getResource` method to the `walk` method. For thi
### Pass a Link Array
-You can also pass an array of strings to the walk method. Makes no difference.
+You can also pass an array of strings to the follow method. Makes no difference.
api.newRequest()
- .walk('first_link', 'second_link', 'third_link')
+ .follow('first_link', 'second_link', 'third_link')
.getResource(callback)
is equivalent to
api.newRequest()
- .walk(['first_link', 'second_link', 'third_link'])
+ .follow(['first_link', 'second_link', 'third_link'])
.getResource(callback)
-If the first argument to `walk` is an array, all remaining arguments will be ignored, though.
+If the first argument to `follow` is an array, all remaining arguments will be ignored, though.
### POST, PUT, DELETE and PATCH
@@ -157,7 +156,7 @@ So far we only have concerned ourselves with fetching information from a REST AP
This looks very similar to using the `get` method:
api.newRequest()
- .walk('link_to', 'resource')
+ .follow('link_to', 'resource')
.post({'some': 'data'}, function(error, response) {
if (error) {
console.error('No luck :-)')
@@ -170,19 +169,19 @@ This looks very similar to using the `get` method:
All methods except `getResource` (that is `get`, `post`, `put`, `delete` and `patch` pass the full http response into the provided callback, so the callback's method signature always looks like `function(error, response)`. `post`, `put` and `patch` obviously have a body argument, `delete` doesn't. Some more examples, just for completenss' sake:
api.newRequest()
- .walk('link_to', 'resource')
+ .follow('link_to', 'resource')
.put({'some': 'data'}, function(error, response) {
...
})
api.newRequest()
- .walk('link_to', 'resource')
+ .follow('link_to', 'resource')
.patch({'some': 'data'}, function(error, response) {
...
})
api.newRequest()
- .walk('link_to', 'resource')
+ .follow('link_to', 'resource')
.delete(function(error, response) {
...
})
@@ -207,7 +206,7 @@ Reasons for failure could be:
Traverson supports [JSONPath](http://goessner.net/articles/JsonPath/) expressions in the path array. This will come in handy if the link you want to follow from a given document is not a direct property of that document. Consider the following example:
api.newRequest()
- .walk('$.deeply.nested.link')
+ .follow('$.deeply.nested.link')
.getResource(function(error, document) {
...
})
@@ -228,7 +227,7 @@ where the document at the root URI is
"the_document": "we wanted to have"
}
-Upon loading the document from the start URI `http://api.io`, Traverson will recognize that the first (and only) link to walk is a JSONPath expression and evaluate it against the given document, which results in the URI `http://api.io/congrats/you/have/found/me`. Of course you can also use path arrays with more than one element with JSONPath and you can freely mix JSONPath expressions with plain vanilla properties.
+Upon loading the document from the start URI `http://api.io`, Traverson will recognize that the first (and only) link to `follow` is a JSONPath expression and evaluate it against the given document, which results in the URI `http://api.io/congrats/you/have/found/me`. Of course you can also use path arrays with more than one element with JSONPath and you can freely mix JSONPath expressions with plain vanilla properties.
Any element of the path array that begins with `$.` or `$[` is assumed to be a JSONPath expression, otherwise the element is interpreted as a plain object property.
@@ -240,7 +239,7 @@ If a JSONPath expressions yields no match or more than one match, an error will
Traverson supports URI templates ([RFC 6570](http://tools.ietf.org/html/rfc6570)). Let's modify our inital example to make use of this feature:
- api.walk('user_thing_lookup')
+ api.follow('user_thing_lookup')
.withTemplateParameters({ user_name: 'basti1302', thing_id: 4711 })
.getResource(function(error, document) {
...
@@ -266,7 +265,7 @@ Of course, URI templating also works if the path from the start URI to the final
Let's assume the following call
- api.walk('user_lookup', 'thing_lookup')
+ api.follow('user_lookup', 'thing_lookup')
.withTemplateParameters({ user_name: 'basti1302', thing_id: 4711 })
.getResource(function(error, document) {
...
@@ -295,7 +294,7 @@ Instead of using a single object to provide the template parameters for each ste
Let's look at an example
- api.walk('user_lookup', 'things', 'thing_lookup')
+ api.follow('user_lookup', 'things', 'thing_lookup')
.withTemplateParameters([null, {id: "basti1302"}, null, {id: 4711} ])
.getResource(function(error, document) {
...
@@ -332,7 +331,7 @@ templates.
Traverson uses Mikeal Rogers' [request](https://github.com/mikeal/request) module for all HTTP requests. You can use all options that `request` provides with Traverson by passing an options object into the `withRequestOptions` method, like this:
- api.walk('link_one', 'link_two', 'link_three')
+ api.follow('link_one', 'link_two', 'link_three')
.withRequestOptions({ headers: { 'x-my-special-header': 'foo' } })
.getResource(function(error, document) {
...
@@ -348,7 +347,7 @@ Traverson supports the JSON dialect of [HAL](http://tools.ietf.org/id/draft-kell
var api = traverson.jsonHal.from('http://haltalk.herokuapp.com/')
api.newRequest()
- .walk('ht:me', 'ht:posts')
+ .follow('ht:me', 'ht:posts')
.withTemplateParameters({name: 'traverson'})
.getResource(function(error, document) {
if (error) {
@@ -422,7 +421,7 @@ This will give you all posts that the account `traverson` posted to Mike Kelly's
#### Embedded Documents
-When working with HAL resources, for each link given to the `walk` method, Traverson checks the `_links` object. If the `_links` object does not have the property in question, Traverson also automatically checks the embedded document (the `_embedded` object). If there is an embedded document with the correct property key, this one will be used instead. If there is both a `_link` and an `_embedded` object with the same name, Traverson will always prefer the link, not the embedded object (reason: the spec says that an embedded resource may "be a full, partial, or inconsistent version of the representation served from the target URI", so to get the complete and up to date document your best bet is to follow the link to the actual resource, if available).
+When working with HAL resources, for each link given to the `follow` method, Traverson checks the `_links` object. If the `_links` object does not have the property in question, Traverson also automatically checks the embedded document (the `_embedded` object). If there is an embedded document with the correct property key, this one will be used instead. If there is both a `_link` and an `_embedded` object with the same name, Traverson will always prefer the link, not the embedded object (reason: the spec says that an embedded resource may "be a full, partial, or inconsistent version of the representation served from the target URI", so to get the complete and up to date document your best bet is to follow the link to the actual resource, if available).
#### HAL and JSONPath
@@ -446,10 +445,6 @@ There will be some simple on/off toggles for certain parts of Traverson behaviou
* disable JSONPath,
* disable caching (a feature yet to be implemented in the first place)
-#### Overriding Parts of Traverson's `walk` Behaviour
-
-TODO
-
### Other Media Types Besides JSON
In the far future, Traverson might also support HTML APIs and/or XML APIs.
View
424 browser/dist/traverson.external.js
@@ -1523,6 +1523,190 @@ if (typeof exports == "object") {
},{"emitter":13,"indexof":13,"reduce":13,"superagent":13}],5:[function(require,module,exports){
'use strict';
+var standardRequest = require('request')
+var util = require('util')
+var JsonWalker = require('./json_walker')
+var JsonHalWalker = require('./json_hal_walker')
+var minilog = require('minilog')
+var mediaTypes = require('./media_types')
+
+var log = minilog('traverson')
+
+function Builder(mediaType, startUri) {
+ this.walker = this.createWalker(mediaType)
+ this.walker.startUri = startUri
+ this.walker.request = this.request = standardRequest
+}
+
+Builder.prototype.createWalker = function(mediaType) {
+ switch (mediaType) {
+ case mediaTypes.JSON:
+ log.debug('creating new JsonWalker')
+ return new JsonWalker()
+ case mediaTypes.JSON_HAL:
+ log.debug('creating new JsonHalWalker')
+ return new JsonHalWalker()
+ default:
+ throw new Error('Unknown or unsupported media type: ' + mediaType)
+ }
+}
+
+Builder.prototype.follow = function() {
+ if (arguments.length === 1 && util.isArray(arguments[0])) {
+ this.walker.links = arguments[0]
+ } else {
+ this.walker.links = Array.prototype.slice.apply(arguments)
+ }
+ return this
+}
+
+Builder.prototype.walk = Builder.prototype.follow
+
+Builder.prototype.withTemplateParameters = function(parameters) {
+ this.walker.templateParameters = parameters
+ return this
+}
+
+Builder.prototype.withRequestOptions = function(options) {
+ this.walker.request = this.request = standardRequest.defaults(options)
+ return this
+}
+
+Builder.prototype.get = function(callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('next step: ' + JSON.stringify(nextStep))
+ self.walker.process(nextStep, function(err, step) {
+ log.debug('walker.process returned')
+ if (err) { return callback(err, step.response, step.uri) }
+ if (!step.response && step.doc) {
+ log.debug('faking HTTP response for embedded resource')
+ step.response = {
+ statusCode: 200,
+ body: JSON.stringify(step.doc),
+ remark: 'This is not an actual HTTP response. The resource you ' +
+ 'requested was an embedded resource, so no HTTP request was ' +
+ 'made to acquire it.'
+ }
+ }
+ // log.debug('returning response')
+ callback(null, step.response)
+ })
+ })
+}
+
+/*
+ * Special variant of get() that does not yield the full http response to the
+ * callback but instead the already parsed JSON as an object.
+ */
+Builder.prototype.getResource = function(callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ // TODO Remove duplication: This duplicates the get/checkHttpStatus/parse
+ // sequence from the Walker's walk method.
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('next step: ' + JSON.stringify(nextStep))
+ self.walker.process(nextStep, function(err, step) {
+ log.debug('walker.process returned')
+ if (err) { return callback(err, step.response, step.uri) }
+ log.debug('resulting step: ' + step.uri)
+ // log.debug('resulting step: ' + JSON.stringify(step))
+
+ if (step.doc) {
+ // return an embedded doc immediately
+ return callback(null, step.doc)
+ }
+
+ var resource
+ try {
+ self.walker.checkHttpStatus(step)
+ resource = self.walker.parse(step)
+ return callback(null, resource)
+ } catch (e) {
+ return callback(e, e.doc)
+ }
+ })
+ })
+}
+
+/*
+ * Special variant of get() that does not execute the last request but instead
+ * yields the last URI to the callback.
+ */
+
+Builder.prototype.getUri = function(callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('returning uri')
+ if (nextStep.uri) {
+ return callback(null, nextStep.uri)
+ } else if (nextStep.doc &&
+ nextStep.doc._links &&
+ nextStep.doc._links.self &&
+ nextStep.doc._links.self.href) {
+ return callback(null, self.walker.startUri +
+ nextStep.doc._links.self.href)
+ } else {
+ return callback(new Error('You requested an URI but the last ' +
+ 'resource is an embedded resource and has no URI of its own ' +
+ '(that is, it has no link with rel=\"self\"'))
+ }
+ })
+}
+
+Builder.prototype.post = function(body, callback) {
+ this.walkAndExecute(body, this.request.post, callback)
+}
+
+Builder.prototype.put = function(body, callback) {
+ this.walkAndExecute(body, this.request.put, callback)
+}
+
+Builder.prototype.patch = function(body, callback) {
+ this.walkAndExecute(body, this.request.patch, callback)
+}
+
+Builder.prototype.delete = function(callback) {
+ this.walkAndExecute(null, this.request.del, callback)
+}
+
+Builder.prototype.walkAndExecute = function(body, method, callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('executing final request with step: ' +
+ JSON.stringify(nextStep))
+ self.executeRequest(nextStep.uri, method, body, callback)
+ })
+}
+
+Builder.prototype.executeRequest = function(uri, method, body,
+ callback) {
+ var options
+ if (body) {
+ options = { body: JSON.stringify(body) }
+ } else {
+ options = {}
+ }
+ log.debug('request to ' + uri + ' with options ' + JSON.stringify(options))
+ method.call(this.request, uri, options, function(err, response) {
+ log.debug('request to ' + uri + ' succeeded')
+ if (err) { return callback(err, response, uri) }
+ return callback(null, response, uri)
+ })
+}
+
+module.exports = Builder
+
+},{"./json_hal_walker":6,"./json_walker":7,"./media_types":8,"minilog":1,"request":3,"util":2}],6:[function(require,module,exports){
+'use strict';
+
var halbert = require('halbert')
var minilog = require('minilog')
var _s = require('underscore.string')
@@ -1575,7 +1759,7 @@ JsonHalWalker.prototype.findEmbedded = function(halResource, link) {
module.exports = JsonHalWalker
-},{"./walker":8,"halbert":14,"minilog":1,"underscore.string":20}],6:[function(require,module,exports){
+},{"./walker":9,"halbert":14,"minilog":1,"underscore.string":20}],7:[function(require,module,exports){
'use strict';
var Walker = require('./walker')
@@ -1586,7 +1770,7 @@ JsonWalker.prototype = new Walker()
module.exports = JsonWalker
-},{"./walker":8}],7:[function(require,module,exports){
+},{"./walker":9}],8:[function(require,module,exports){
'use strict';
module.exports = {
@@ -1594,7 +1778,7 @@ module.exports = {
JSON_HAL: 'application/hal+json'
}
-},{}],8:[function(require,module,exports){
+},{}],9:[function(require,module,exports){
'use strict';
var jsonpathLib = require('JSONPath')
@@ -1614,36 +1798,9 @@ function Walker() {
}
/*
- * Fetches the document from this.startUri and then, starting with the first
- * element from the array this.links:
- * 1) uses the next element from this.links as the property key.
- * If the next element starts with $. or $[ it is assumed that it is a
- * JSONPath expression, otherwise it is assumed to be a simple property
- * key.
- * 2) Looks for the property key in the fetched document or evaluates the
- * JSONPath expression. In the latter case, there must be exactly one
- * non-ambigious match, otherwise an error is passed to the callback.
- * 3) If the result of step 2 is an URI template, it is evaluated with
- * this.templateParameters, otherwise it is interpreted as an URI as is.
- * 4) Passes the resulting URI to this.get to acquire the next document.
- * 5) Goes back to step 1) with the next element from the this.links, if any.
- *
- * When the this.links has been consumed completely by the above procedure),
- * the given callback is called with a result object, containing three
- * properties:
- * - nextUri: the nextUri to access (depending on which method has been
- * called on WalkerBuilder, this will be a get/post/put/... request),
- * - lastUri: the last URI that the walker has accessed,
- * - lastResponse: the HTTP response from accessing lastUri
- *
- * This method uses the following properties of the this-context, which need
- * to be set by the caller in advance:
- * - this.startUri is the first URI to get (usually the root URI of the API)
- * - this.links is an array of property keys/JSONPath expressions.
- * - this.templateParameters is an object or an array of objects, containaing
- * the template parameters for each element in this.links. Can be null.
- * Also, individual elements can be null.
- * - this.request is the request API object to use
+ * Walks from resource to resource along the path given by the link relations
+ * from this.links until it has reached the last URI. On reaching this, it calls
+ * the given callback with the last resulting step.
*/
Walker.prototype.walk = function(callback) {
@@ -1656,8 +1813,8 @@ Walker.prototype.walk = function(callback) {
var finalStep = nextStep
log.debug('starting to follow links')
- ;
- (function executeNextRequest() {
+
+ function executeNextStep() {
if (index < self.links.length) {
// Trigger execution of next step. In most cases that is an HTTP get to
@@ -1713,7 +1870,7 @@ Walker.prototype.walk = function(callback) {
}
// follow next link
- executeNextRequest()
+ executeNextStep()
})
} else {
// link array is exhausted, we are done and return the last response
@@ -1721,7 +1878,8 @@ Walker.prototype.walk = function(callback) {
log.debug('link array exhausted, calling callback')
return callback(null, nextStep, finalStep)
}
- })()
+ }
+ executeNextStep()
}
Walker.prototype.process = function(step, callback) {
@@ -1875,189 +2033,7 @@ function jsonError(uri, body) {
module.exports = Walker
-},{"JSONPath":10,"minilog":1,"underscore.string":20,"uri-template":21,"util":2}],9:[function(require,module,exports){
-'use strict';
-
-var standardRequest = require('request')
-var util = require('util')
-var JsonWalker = require('./json_walker')
-var JsonHalWalker = require('./json_hal_walker')
-var minilog = require('minilog')
-var mediaTypes = require('./media_types')
-
-var log = minilog('traverson')
-
-function WalkerBuilder(mediaType, startUri) {
- this.walker = this.createWalker(mediaType)
- this.walker.startUri = startUri
- this.walker.request = this.request = standardRequest
-}
-
-WalkerBuilder.prototype.createWalker = function(mediaType) {
- switch (mediaType) {
- case mediaTypes.JSON:
- log.debug('creating new JsonWalker')
- return new JsonWalker()
- case mediaTypes.JSON_HAL:
- log.debug('creating new JsonHalWalker')
- return new JsonHalWalker()
- default:
- throw new Error('Unknown or unsupported media type: ' + mediaType)
- }
-}
-
-WalkerBuilder.prototype.walk = function() {
- if (arguments.length === 1 && util.isArray(arguments[0])) {
- this.walker.links = arguments[0]
- } else {
- this.walker.links = Array.prototype.slice.apply(arguments)
- }
- return this
-}
-
-WalkerBuilder.prototype.withTemplateParameters = function(parameters) {
- this.walker.templateParameters = parameters
- return this
-}
-
-WalkerBuilder.prototype.withRequestOptions = function(options) {
- this.walker.request = this.request = standardRequest.defaults(options)
- return this
-}
-
-WalkerBuilder.prototype.get = function(callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('next step: ' + JSON.stringify(nextStep))
- self.walker.process(nextStep, function(err, step) {
- log.debug('walker.process returned')
- if (err) { return callback(err, step.response, step.uri) }
- if (!step.response && step.doc) {
- log.debug('faking HTTP response for embedded resource')
- step.response = {
- statusCode: 200,
- body: JSON.stringify(step.doc),
- remark: 'This is not an actual HTTP response. The resource you ' +
- 'requested was an embedded resource, so no HTTP request was ' +
- 'made to acquire it.'
- }
- }
- // log.debug('returning response')
- callback(null, step.response)
- })
- })
-}
-
-/*
- * Special variant of get() that does not yield the full http response to the
- * callback but instead the already parsed JSON as an object.
- */
-WalkerBuilder.prototype.getResource = function(callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- // TODO Remove duplication: This duplicates the get/checkHttpStatus/parse
- // sequence from the Walker's walk method.
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('next step: ' + JSON.stringify(nextStep))
- self.walker.process(nextStep, function(err, step) {
- log.debug('walker.process returned')
- if (err) { return callback(err, step.response, step.uri) }
- log.debug('resulting step: ' + step.uri)
- // log.debug('resulting step: ' + JSON.stringify(step))
-
- if (step.doc) {
- // return an embedded doc immediately
- return callback(null, step.doc)
- }
-
- var resource
- try {
- self.walker.checkHttpStatus(step)
- resource = self.walker.parse(step)
- return callback(null, resource)
- } catch (e) {
- return callback(e, e.doc)
- }
- })
- })
-}
-
-/*
- * Special variant of get() that does not execute the last request but instead
- * yields the last URI to the callback.
- */
-
-WalkerBuilder.prototype.getUri = function(callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('returning uri')
- if (nextStep.uri) {
- return callback(null, nextStep.uri)
- } else if (nextStep.doc &&
- nextStep.doc._links &&
- nextStep.doc._links.self &&
- nextStep.doc._links.self.href) {
- return callback(null, self.walker.startUri +
- nextStep.doc._links.self.href)
- } else {
- return callback(new Error('You requested an URI but the last ' +
- 'resource is an embedded resource and has no URI of its own ' +
- '(that is, it has no link with rel=\"self\"'))
- }
- })
-}
-
-WalkerBuilder.prototype.post = function(body, callback) {
- this.walkAndExecute(body, this.request.post, callback)
-}
-
-WalkerBuilder.prototype.put = function(body, callback) {
- this.walkAndExecute(body, this.request.put, callback)
-}
-
-WalkerBuilder.prototype.patch = function(body, callback) {
- this.walkAndExecute(body, this.request.patch, callback)
-}
-
-WalkerBuilder.prototype.delete = function(callback) {
- this.walkAndExecute(null, this.request.del, callback)
-}
-
-WalkerBuilder.prototype.walkAndExecute = function(body, method, callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('executing final request with step: ' +
- JSON.stringify(nextStep))
- self.executeRequest(nextStep.uri, method, body, callback)
- })
-}
-
-WalkerBuilder.prototype.executeRequest = function(uri, method, body,
- callback) {
- var options
- if (body) {
- options = { body: JSON.stringify(body) }
- } else {
- options = {}
- }
- log.debug('request to ' + uri + ' with options ' + JSON.stringify(options))
- method.call(this.request, uri, options, function(err, response) {
- log.debug('request to ' + uri + ' succeeded')
- if (err) { return callback(err, response, uri) }
- return callback(null, response, uri)
- })
-}
-
-module.exports = WalkerBuilder
-
-},{"./json_hal_walker":5,"./json_walker":6,"./media_types":7,"minilog":1,"request":3,"util":2}],10:[function(require,module,exports){
+},{"JSONPath":10,"minilog":1,"underscore.string":20,"uri-template":21,"util":2}],10:[function(require,module,exports){
/* JSONPath 0.8.0 - XPath for JSON
*
* Copyright (c) 2007 Stefan Goessner (goessner.net)
@@ -11742,7 +11718,7 @@ module.exports=require('5u5bvt');
var minilog = require('minilog')
var mediaTypes = require('./lib/media_types')
-var WalkerBuilder = require('./lib/walker_builder')
+var Builder = require('./lib/builder')
// activate this line to enable logging
// require('minilog').enable();
@@ -11752,7 +11728,7 @@ module.exports = {
from: function(uri) {
return {
newRequest: function() {
- return new WalkerBuilder(mediaTypes.JSON, uri)
+ return new Builder(mediaTypes.JSON, uri)
}
}
}
@@ -11761,12 +11737,12 @@ module.exports = {
from: function(uri) {
return {
newRequest: function() {
- return new WalkerBuilder(mediaTypes.JSON_HAL, uri)
+ return new Builder(mediaTypes.JSON_HAL, uri)
}
}
}
}
}
-},{"./lib/media_types":7,"./lib/walker_builder":9,"minilog":1}]},{},["5u5bvt"])
+},{"./lib/builder":5,"./lib/media_types":8,"minilog":1}]},{},["5u5bvt"])
;
View
6 browser/dist/traverson.external.min.js
3 additions, 3 deletions not shown
View
424 browser/dist/traverson.js
@@ -1524,6 +1524,190 @@ if (typeof exports == "object") {
},{"emitter":13,"indexof":13,"reduce":13,"superagent":13}],5:[function(require,module,exports){
'use strict';
+var standardRequest = require('request')
+var util = require('util')
+var JsonWalker = require('./json_walker')
+var JsonHalWalker = require('./json_hal_walker')
+var minilog = require('minilog')
+var mediaTypes = require('./media_types')
+
+var log = minilog('traverson')
+
+function Builder(mediaType, startUri) {
+ this.walker = this.createWalker(mediaType)
+ this.walker.startUri = startUri
+ this.walker.request = this.request = standardRequest
+}
+
+Builder.prototype.createWalker = function(mediaType) {
+ switch (mediaType) {
+ case mediaTypes.JSON:
+ log.debug('creating new JsonWalker')
+ return new JsonWalker()
+ case mediaTypes.JSON_HAL:
+ log.debug('creating new JsonHalWalker')
+ return new JsonHalWalker()
+ default:
+ throw new Error('Unknown or unsupported media type: ' + mediaType)
+ }
+}
+
+Builder.prototype.follow = function() {
+ if (arguments.length === 1 && util.isArray(arguments[0])) {
+ this.walker.links = arguments[0]
+ } else {
+ this.walker.links = Array.prototype.slice.apply(arguments)
+ }
+ return this
+}
+
+Builder.prototype.walk = Builder.prototype.follow
+
+Builder.prototype.withTemplateParameters = function(parameters) {
+ this.walker.templateParameters = parameters
+ return this
+}
+
+Builder.prototype.withRequestOptions = function(options) {
+ this.walker.request = this.request = standardRequest.defaults(options)
+ return this
+}
+
+Builder.prototype.get = function(callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('next step: ' + JSON.stringify(nextStep))
+ self.walker.process(nextStep, function(err, step) {
+ log.debug('walker.process returned')
+ if (err) { return callback(err, step.response, step.uri) }
+ if (!step.response && step.doc) {
+ log.debug('faking HTTP response for embedded resource')
+ step.response = {
+ statusCode: 200,
+ body: JSON.stringify(step.doc),
+ remark: 'This is not an actual HTTP response. The resource you ' +
+ 'requested was an embedded resource, so no HTTP request was ' +
+ 'made to acquire it.'
+ }
+ }
+ // log.debug('returning response')
+ callback(null, step.response)
+ })
+ })
+}
+
+/*
+ * Special variant of get() that does not yield the full http response to the
+ * callback but instead the already parsed JSON as an object.
+ */
+Builder.prototype.getResource = function(callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ // TODO Remove duplication: This duplicates the get/checkHttpStatus/parse
+ // sequence from the Walker's walk method.
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('next step: ' + JSON.stringify(nextStep))
+ self.walker.process(nextStep, function(err, step) {
+ log.debug('walker.process returned')
+ if (err) { return callback(err, step.response, step.uri) }
+ log.debug('resulting step: ' + step.uri)
+ // log.debug('resulting step: ' + JSON.stringify(step))
+
+ if (step.doc) {
+ // return an embedded doc immediately
+ return callback(null, step.doc)
+ }
+
+ var resource
+ try {
+ self.walker.checkHttpStatus(step)
+ resource = self.walker.parse(step)
+ return callback(null, resource)
+ } catch (e) {
+ return callback(e, e.doc)
+ }
+ })
+ })
+}
+
+/*
+ * Special variant of get() that does not execute the last request but instead
+ * yields the last URI to the callback.
+ */
+
+Builder.prototype.getUri = function(callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('returning uri')
+ if (nextStep.uri) {
+ return callback(null, nextStep.uri)
+ } else if (nextStep.doc &&
+ nextStep.doc._links &&
+ nextStep.doc._links.self &&
+ nextStep.doc._links.self.href) {
+ return callback(null, self.walker.startUri +
+ nextStep.doc._links.self.href)
+ } else {
+ return callback(new Error('You requested an URI but the last ' +
+ 'resource is an embedded resource and has no URI of its own ' +
+ '(that is, it has no link with rel=\"self\"'))
+ }
+ })
+}
+
+Builder.prototype.post = function(body, callback) {
+ this.walkAndExecute(body, this.request.post, callback)
+}
+
+Builder.prototype.put = function(body, callback) {
+ this.walkAndExecute(body, this.request.put, callback)
+}
+
+Builder.prototype.patch = function(body, callback) {
+ this.walkAndExecute(body, this.request.patch, callback)
+}
+
+Builder.prototype.delete = function(callback) {
+ this.walkAndExecute(null, this.request.del, callback)
+}
+
+Builder.prototype.walkAndExecute = function(body, method, callback) {
+ var self = this
+ this.walker.walk(function(err, nextStep, lastStep) {
+ log.debug('walker.walk returned')
+ if (err) { return callback(err, lastStep.response, lastStep.uri) }
+ log.debug('executing final request with step: ' +
+ JSON.stringify(nextStep))
+ self.executeRequest(nextStep.uri, method, body, callback)
+ })
+}
+
+Builder.prototype.executeRequest = function(uri, method, body,
+ callback) {
+ var options
+ if (body) {
+ options = { body: JSON.stringify(body) }
+ } else {
+ options = {}
+ }
+ log.debug('request to ' + uri + ' with options ' + JSON.stringify(options))
+ method.call(this.request, uri, options, function(err, response) {
+ log.debug('request to ' + uri + ' succeeded')
+ if (err) { return callback(err, response, uri) }
+ return callback(null, response, uri)
+ })
+}
+
+module.exports = Builder
+
+},{"./json_hal_walker":6,"./json_walker":7,"./media_types":8,"minilog":1,"request":3,"util":2}],6:[function(require,module,exports){
+'use strict';
+
var halbert = require('halbert')
var minilog = require('minilog')
var _s = require('underscore.string')
@@ -1576,7 +1760,7 @@ JsonHalWalker.prototype.findEmbedded = function(halResource, link) {
module.exports = JsonHalWalker
-},{"./walker":8,"halbert":14,"minilog":1,"underscore.string":20}],6:[function(require,module,exports){
+},{"./walker":9,"halbert":14,"minilog":1,"underscore.string":20}],7:[function(require,module,exports){
'use strict';
var Walker = require('./walker')
@@ -1587,7 +1771,7 @@ JsonWalker.prototype = new Walker()
module.exports = JsonWalker
-},{"./walker":8}],7:[function(require,module,exports){
+},{"./walker":9}],8:[function(require,module,exports){
'use strict';
module.exports = {
@@ -1595,7 +1779,7 @@ module.exports = {
JSON_HAL: 'application/hal+json'
}
-},{}],8:[function(require,module,exports){
+},{}],9:[function(require,module,exports){
'use strict';
var jsonpathLib = require('JSONPath')
@@ -1615,36 +1799,9 @@ function Walker() {
}
/*
- * Fetches the document from this.startUri and then, starting with the first
- * element from the array this.links:
- * 1) uses the next element from this.links as the property key.
- * If the next element starts with $. or $[ it is assumed that it is a
- * JSONPath expression, otherwise it is assumed to be a simple property
- * key.
- * 2) Looks for the property key in the fetched document or evaluates the
- * JSONPath expression. In the latter case, there must be exactly one
- * non-ambigious match, otherwise an error is passed to the callback.
- * 3) If the result of step 2 is an URI template, it is evaluated with
- * this.templateParameters, otherwise it is interpreted as an URI as is.
- * 4) Passes the resulting URI to this.get to acquire the next document.
- * 5) Goes back to step 1) with the next element from the this.links, if any.
- *
- * When the this.links has been consumed completely by the above procedure),
- * the given callback is called with a result object, containing three
- * properties:
- * - nextUri: the nextUri to access (depending on which method has been
- * called on WalkerBuilder, this will be a get/post/put/... request),
- * - lastUri: the last URI that the walker has accessed,
- * - lastResponse: the HTTP response from accessing lastUri
- *
- * This method uses the following properties of the this-context, which need
- * to be set by the caller in advance:
- * - this.startUri is the first URI to get (usually the root URI of the API)
- * - this.links is an array of property keys/JSONPath expressions.
- * - this.templateParameters is an object or an array of objects, containaing
- * the template parameters for each element in this.links. Can be null.
- * Also, individual elements can be null.
- * - this.request is the request API object to use
+ * Walks from resource to resource along the path given by the link relations
+ * from this.links until it has reached the last URI. On reaching this, it calls
+ * the given callback with the last resulting step.
*/
Walker.prototype.walk = function(callback) {
@@ -1657,8 +1814,8 @@ Walker.prototype.walk = function(callback) {
var finalStep = nextStep
log.debug('starting to follow links')
- ;
- (function executeNextRequest() {
+
+ function executeNextStep() {
if (index < self.links.length) {
// Trigger execution of next step. In most cases that is an HTTP get to
@@ -1714,7 +1871,7 @@ Walker.prototype.walk = function(callback) {
}
// follow next link
- executeNextRequest()
+ executeNextStep()
})
} else {
// link array is exhausted, we are done and return the last response
@@ -1722,7 +1879,8 @@ Walker.prototype.walk = function(callback) {
log.debug('link array exhausted, calling callback')
return callback(null, nextStep, finalStep)
}
- })()
+ }
+ executeNextStep()
}
Walker.prototype.process = function(step, callback) {
@@ -1876,189 +2034,7 @@ function jsonError(uri, body) {
module.exports = Walker
-},{"JSONPath":10,"minilog":1,"underscore.string":20,"uri-template":21,"util":2}],9:[function(require,module,exports){
-'use strict';
-
-var standardRequest = require('request')
-var util = require('util')
-var JsonWalker = require('./json_walker')
-var JsonHalWalker = require('./json_hal_walker')
-var minilog = require('minilog')
-var mediaTypes = require('./media_types')
-
-var log = minilog('traverson')
-
-function WalkerBuilder(mediaType, startUri) {
- this.walker = this.createWalker(mediaType)
- this.walker.startUri = startUri
- this.walker.request = this.request = standardRequest
-}
-
-WalkerBuilder.prototype.createWalker = function(mediaType) {
- switch (mediaType) {
- case mediaTypes.JSON:
- log.debug('creating new JsonWalker')
- return new JsonWalker()
- case mediaTypes.JSON_HAL:
- log.debug('creating new JsonHalWalker')
- return new JsonHalWalker()
- default:
- throw new Error('Unknown or unsupported media type: ' + mediaType)
- }
-}
-
-WalkerBuilder.prototype.walk = function() {
- if (arguments.length === 1 && util.isArray(arguments[0])) {
- this.walker.links = arguments[0]
- } else {
- this.walker.links = Array.prototype.slice.apply(arguments)
- }
- return this
-}
-
-WalkerBuilder.prototype.withTemplateParameters = function(parameters) {
- this.walker.templateParameters = parameters
- return this
-}
-
-WalkerBuilder.prototype.withRequestOptions = function(options) {
- this.walker.request = this.request = standardRequest.defaults(options)
- return this
-}
-
-WalkerBuilder.prototype.get = function(callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('next step: ' + JSON.stringify(nextStep))
- self.walker.process(nextStep, function(err, step) {
- log.debug('walker.process returned')
- if (err) { return callback(err, step.response, step.uri) }
- if (!step.response && step.doc) {
- log.debug('faking HTTP response for embedded resource')
- step.response = {
- statusCode: 200,
- body: JSON.stringify(step.doc),
- remark: 'This is not an actual HTTP response. The resource you ' +
- 'requested was an embedded resource, so no HTTP request was ' +
- 'made to acquire it.'
- }
- }
- // log.debug('returning response')
- callback(null, step.response)
- })
- })
-}
-
-/*
- * Special variant of get() that does not yield the full http response to the
- * callback but instead the already parsed JSON as an object.
- */
-WalkerBuilder.prototype.getResource = function(callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- // TODO Remove duplication: This duplicates the get/checkHttpStatus/parse
- // sequence from the Walker's walk method.
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('next step: ' + JSON.stringify(nextStep))
- self.walker.process(nextStep, function(err, step) {
- log.debug('walker.process returned')
- if (err) { return callback(err, step.response, step.uri) }
- log.debug('resulting step: ' + step.uri)
- // log.debug('resulting step: ' + JSON.stringify(step))
-
- if (step.doc) {
- // return an embedded doc immediately
- return callback(null, step.doc)
- }
-
- var resource
- try {
- self.walker.checkHttpStatus(step)
- resource = self.walker.parse(step)
- return callback(null, resource)
- } catch (e) {
- return callback(e, e.doc)
- }
- })
- })
-}
-
-/*
- * Special variant of get() that does not execute the last request but instead
- * yields the last URI to the callback.
- */
-
-WalkerBuilder.prototype.getUri = function(callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('returning uri')
- if (nextStep.uri) {
- return callback(null, nextStep.uri)
- } else if (nextStep.doc &&
- nextStep.doc._links &&
- nextStep.doc._links.self &&
- nextStep.doc._links.self.href) {
- return callback(null, self.walker.startUri +
- nextStep.doc._links.self.href)
- } else {
- return callback(new Error('You requested an URI but the last ' +
- 'resource is an embedded resource and has no URI of its own ' +
- '(that is, it has no link with rel=\"self\"'))
- }
- })
-}
-
-WalkerBuilder.prototype.post = function(body, callback) {
- this.walkAndExecute(body, this.request.post, callback)
-}
-
-WalkerBuilder.prototype.put = function(body, callback) {
- this.walkAndExecute(body, this.request.put, callback)
-}
-
-WalkerBuilder.prototype.patch = function(body, callback) {
- this.walkAndExecute(body, this.request.patch, callback)
-}
-
-WalkerBuilder.prototype.delete = function(callback) {
- this.walkAndExecute(null, this.request.del, callback)
-}
-
-WalkerBuilder.prototype.walkAndExecute = function(body, method, callback) {
- var self = this
- this.walker.walk(function(err, nextStep, lastStep) {
- log.debug('walker.walk returned')
- if (err) { return callback(err, lastStep.response, lastStep.uri) }
- log.debug('executing final request with step: ' +
- JSON.stringify(nextStep))
- self.executeRequest(nextStep.uri, method, body, callback)
- })
-}
-
-WalkerBuilder.prototype.executeRequest = function(uri, method, body,
- callback) {
- var options
- if (body) {
- options = { body: JSON.stringify(body) }
- } else {
- options = {}
- }
- log.debug('request to ' + uri + ' with options ' + JSON.stringify(options))
- method.call(this.request, uri, options, function(err, response) {
- log.debug('request to ' + uri + ' succeeded')
- if (err) { return callback(err, response, uri) }
- return callback(null, response, uri)
- })
-}
-
-module.exports = WalkerBuilder
-
-},{"./json_hal_walker":5,"./json_walker":6,"./media_types":7,"minilog":1,"request":3,"util":2}],10:[function(require,module,exports){
+},{"JSONPath":10,"minilog":1,"underscore.string":20,"uri-template":21,"util":2}],10:[function(require,module,exports){
/* JSONPath 0.8.0 - XPath for JSON
*
* Copyright (c) 2007 Stefan Goessner (goessner.net)
@@ -11741,7 +11717,7 @@ module.exports = function pctEncode(regexp) {
var minilog = require('minilog')
var mediaTypes = require('./lib/media_types')
-var WalkerBuilder = require('./lib/walker_builder')
+var Builder = require('./lib/builder')
// activate this line to enable logging
// require('minilog').enable();
@@ -11751,7 +11727,7 @@ module.exports = {
from: function(uri) {
return {
newRequest: function() {
- return new WalkerBuilder(mediaTypes.JSON, uri)
+ return new Builder(mediaTypes.JSON, uri)
}
}
}
@@ -11760,14 +11736,14 @@ module.exports = {
from: function(uri) {
return {
newRequest: function() {
- return new WalkerBuilder(mediaTypes.JSON_HAL, uri)
+ return new Builder(mediaTypes.JSON_HAL, uri)
}
}
}
}
}
-},{"./lib/media_types":7,"./lib/walker_builder":9,"minilog":1}]},{},[25])
+},{"./lib/builder":5,"./lib/media_types":8,"minilog":1}]},{},[25])
(25)
});
;
View
6 browser/dist/traverson.min.js
3 additions, 3 deletions not shown
View
16 browser/example/traverson-examples.js
@@ -25,7 +25,7 @@
jsonApi
.newRequest()
.withRequestOptions({ headers: { 'accept': 'application/json' } })
- .walk('second', 'doc')
+ .follow('second', 'doc')
.getResource(function(err, resource) {
if (err) {
$('#plain_vanilla_response').html(JSON.stringify(err))
@@ -41,7 +41,7 @@
jsonApi
.newRequest()
.withRequestOptions({ headers: { 'accept': 'application/json' } })
- .walk('$.jsonpath.nested.key')
+ .follow('$.jsonpath.nested.key')
.getResource(function(err, resource) {
if (err) {
$('#jsonpath_response').html(JSON.stringify(err))
@@ -57,7 +57,7 @@
jsonApi
.newRequest()
.withRequestOptions({ headers: { 'accept': 'application/json' } })
- .walk('uri_template')
+ .follow('uri_template')
.withTemplateParameters({param: 'foobar', id: 13})
.getResource(function(err, resource) {
if (err) {
@@ -74,7 +74,7 @@
jsonHalApi
.newRequest()
.withRequestOptions({ headers: { 'accept': 'application/hal+json' } })
- .walk('first', 'second', 'inside_second')
+ .follow('first', 'second', 'inside_second')
.getResource(function(err, resource) {
if (err) {
$('#json_hal_response').html(JSON.stringify(err))
@@ -102,7 +102,7 @@
'.withRequestOptions({<br/>' +
'&nbsp;&nbsp;headers: { \'accept\': \'application/json\' }<br/>' +
'})<br/>' +
- '.walk(\'second\', \'doc\')<br/>' +
+ '.follow(\'second\', \'doc\')<br/>' +
'.getResource(function(err, resource) {<br/>' +
'&nbsp;&nbsp;// do something with the resource...<br/>' +
'})<br/>'
@@ -114,7 +114,7 @@
'.withRequestOptions({<br/>' +
'&nbsp;&nbsp;headers: { \'accept\': \'application/json\' }<br/>' +
'})<br/>' +
- '.walk(\'$.jsonpath.nested.key\')<br/>' +
+ '.follow(\'$.jsonpath.nested.key\')<br/>' +
'.getResource(function(err, resource) {<br/>' +
'&nbsp;&nbsp;// do something with the resource...<br/>' +
'})<br/>'
@@ -126,7 +126,7 @@
'.withRequestOptions({<br/>' +
'&nbsp;&nbsp;headers: { \'accept\': \'application/json\' }<br/>' +
'})<br/>' +
- '.walk(\'uri_template\')<br/>' +
+ '.follow(\'uri_template\')<br/>' +
'.withTemplateParameters({param: \'foobar\', id: 13})<br/>' +
'.getResource(function(err, resource) {<br/>' +
'&nbsp;&nbsp;// do something with the resource...<br/>' +
@@ -139,7 +139,7 @@
'.withRequestOptions({<br/>' +
'&nbsp;&nbsp;headers: { \'accept\': \'application/hal+json\' }<br/>' +
'})<br/>' +
- '.walk(\'first\', \'second\', \'inside_second\')<br/>' +
+ '.follow(\'first\', \'second\', \'inside_second\')<br/>' +
'.getResource(function(err, resource) {<br/>' +
'&nbsp;&nbsp;// do something with the resource...<br/>' +
'})<br/>'
View
164 browser/test/browserified_tests.js
82 additions, 82 deletions not shown
View
16 haltalk_test/haltalk.js
@@ -43,7 +43,7 @@ describe('Traverson (when tested against the haltalk server at ' + rootUri +
})
it('should fetch the root response', function(done) {
- api.walk().get(callback)
+ api.follow().get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -56,7 +56,7 @@ describe('Traverson (when tested against the haltalk server at ' + rootUri +
})
it('should fetch the root document', function(done) {
- api.walk().getResource(callback)
+ api.follow().getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -68,8 +68,8 @@ describe('Traverson (when tested against the haltalk server at ' + rootUri +
)
})
- it('should walk a single element path', function(done) {
- api.walk('ht:users').getResource(callback)
+ it('should follow a single element path', function(done) {
+ api.follow('ht:users').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -80,9 +80,9 @@ describe('Traverson (when tested against the haltalk server at ' + rootUri +
)
})
- it('should walk a multi-element path with templating and embedded docs',
+ it('should follow a multi-element path with templating and embedded docs',
function(done) {
- api.walk('ht:me', 'ht:posts', 'ht:post')
+ api.follow('ht:me', 'ht:posts', 'ht:post')
.withTemplateParameters({name: 'mike'})
.get(callback)
waitFor(
@@ -108,7 +108,7 @@ describe('Traverson (when tested against the haltalk server at ' + rootUri +
'password': password,
'real_name': realName
}
- api.walk('ht:signup').post(body, callback)
+ api.follow('ht:signup').post(body, callback)
waitFor(
function() { return callback.called },
function() {
@@ -140,7 +140,7 @@ describe('Traverson (when tested against the haltalk server at ' + rootUri +
pass: 'traverson',
sendImmediately: true
}
- }).walk('ht:me', 'ht:posts')
+ }).follow('ht:me', 'ht:posts')
.withTemplateParameters({ name: 'traverson' })
.post(body, callback)
waitFor(
View
32 lib/walker_builder.js → lib/builder.js
@@ -9,13 +9,13 @@ var mediaTypes = require('./media_types')
var log = minilog('traverson')
-function WalkerBuilder(mediaType, startUri) {
+function Builder(mediaType, startUri) {
this.walker = this.createWalker(mediaType)
this.walker.startUri = startUri
this.walker.request = this.request = standardRequest
}
-WalkerBuilder.prototype.createWalker = function(mediaType) {
+Builder.prototype.createWalker = function(mediaType) {
switch (mediaType) {
case mediaTypes.JSON:
log.debug('creating new JsonWalker')
@@ -28,7 +28,7 @@ WalkerBuilder.prototype.createWalker = function(mediaType) {
}
}
-WalkerBuilder.prototype.walk = function() {
+Builder.prototype.follow = function() {
if (arguments.length === 1 && util.isArray(arguments[0])) {
this.walker.links = arguments[0]
} else {
@@ -37,17 +37,19 @@ WalkerBuilder.prototype.walk = function() {
return this
}
-WalkerBuilder.prototype.withTemplateParameters = function(parameters) {
+Builder.prototype.walk = Builder.prototype.follow
+
+Builder.prototype.withTemplateParameters = function(parameters) {
this.walker.templateParameters = parameters
return this
}
-WalkerBuilder.prototype.withRequestOptions = function(options) {
+Builder.prototype.withRequestOptions = function(options) {
this.walker.request = this.request = standardRequest.defaults(options)
return this
}
-WalkerBuilder.prototype.get = function(callback) {
+Builder.prototype.get = function(callback) {
var self = this
this.walker.walk(function(err, nextStep, lastStep) {
log.debug('walker.walk returned')
@@ -76,7 +78,7 @@ WalkerBuilder.prototype.get = function(callback) {
* Special variant of get() that does not yield the full http response to the
* callback but instead the already parsed JSON as an object.
*/
-WalkerBuilder.prototype.getResource = function(callback) {
+Builder.prototype.getResource = function(callback) {
var self = this
this.walker.walk(function(err, nextStep, lastStep) {
// TODO Remove duplication: This duplicates the get/checkHttpStatus/parse
@@ -112,7 +114,7 @@ WalkerBuilder.prototype.getResource = function(callback) {
* yields the last URI to the callback.
*/
-WalkerBuilder.prototype.getUri = function(callback) {
+Builder.prototype.getUri = function(callback) {
var self = this
this.walker.walk(function(err, nextStep, lastStep) {
log.debug('walker.walk returned')
@@ -134,23 +136,23 @@ WalkerBuilder.prototype.getUri = function(callback) {
})
}
-WalkerBuilder.prototype.post = function(body, callback) {
+Builder.prototype.post = function(body, callback) {
this.walkAndExecute(body, this.request.post, callback)
}
-WalkerBuilder.prototype.put = function(body, callback) {
+Builder.prototype.put = function(body, callback) {
this.walkAndExecute(body, this.request.put, callback)
}
-WalkerBuilder.prototype.patch = function(body, callback) {
+Builder.prototype.patch = function(body, callback) {
this.walkAndExecute(body, this.request.patch, callback)
}
-WalkerBuilder.prototype.delete = function(callback) {
+Builder.prototype.delete = function(callback) {
this.walkAndExecute(null, this.request.del, callback)
}
-WalkerBuilder.prototype.walkAndExecute = function(body, method, callback) {
+Builder.prototype.walkAndExecute = function(body, method, callback) {
var self = this
this.walker.walk(function(err, nextStep, lastStep) {
log.debug('walker.walk returned')
@@ -161,7 +163,7 @@ WalkerBuilder.prototype.walkAndExecute = function(body, method, callback) {
})
}
-WalkerBuilder.prototype.executeRequest = function(uri, method, body,
+Builder.prototype.executeRequest = function(uri, method, body,
callback) {
var options
if (body) {
@@ -177,4 +179,4 @@ WalkerBuilder.prototype.executeRequest = function(uri, method, body,
})
}
-module.exports = WalkerBuilder
+module.exports = Builder
View
42 lib/walker.js
@@ -17,36 +17,9 @@ function Walker() {
}
/*
- * Fetches the document from this.startUri and then, starting with the first
- * element from the array this.links:
- * 1) uses the next element from this.links as the property key.
- * If the next element starts with $. or $[ it is assumed that it is a
- * JSONPath expression, otherwise it is assumed to be a simple property
- * key.
- * 2) Looks for the property key in the fetched document or evaluates the
- * JSONPath expression. In the latter case, there must be exactly one
- * non-ambigious match, otherwise an error is passed to the callback.
- * 3) If the result of step 2 is an URI template, it is evaluated with
- * this.templateParameters, otherwise it is interpreted as an URI as is.
- * 4) Passes the resulting URI to this.get to acquire the next document.
- * 5) Goes back to step 1) with the next element from the this.links, if any.
- *
- * When the this.links has been consumed completely by the above procedure),
- * the given callback is called with a result object, containing three
- * properties:
- * - nextUri: the nextUri to access (depending on which method has been
- * called on WalkerBuilder, this will be a get/post/put/... request),
- * - lastUri: the last URI that the walker has accessed,
- * - lastResponse: the HTTP response from accessing lastUri
- *
- * This method uses the following properties of the this-context, which need
- * to be set by the caller in advance:
- * - this.startUri is the first URI to get (usually the root URI of the API)
- * - this.links is an array of property keys/JSONPath expressions.
- * - this.templateParameters is an object or an array of objects, containaing
- * the template parameters for each element in this.links. Can be null.
- * Also, individual elements can be null.
- * - this.request is the request API object to use
+ * Walks from resource to resource along the path given by the link relations
+ * from this.links until it has reached the last URI. On reaching this, it calls
+ * the given callback with the last resulting step.
*/
Walker.prototype.walk = function(callback) {
@@ -59,8 +32,8 @@ Walker.prototype.walk = function(callback) {
var finalStep = nextStep
log.debug('starting to follow links')
- ;
- (function executeNextRequest() {
+
+ function executeNextStep() {
if (index < self.links.length) {
// Trigger execution of next step. In most cases that is an HTTP get to
@@ -116,7 +89,7 @@ Walker.prototype.walk = function(callback) {
}
// follow next link
- executeNextRequest()
+ executeNextStep()
})
} else {
// link array is exhausted, we are done and return the last response
@@ -124,7 +97,8 @@ Walker.prototype.walk = function(callback) {
log.debug('link array exhausted, calling callback')
return callback(null, nextStep, finalStep)
}
- })()
+ }
+ executeNextStep()
}
Walker.prototype.process = function(step, callback) {
View
36 test/json_get_resource.js
@@ -39,13 +39,13 @@ describe('getResource for JSON', function() {
})
it('should access the root URI', function() {
- api.walk().getResource(callback)
+ api.follow().getResource(callback)
expect(get).to.have.been.calledWith(rootUri, sinon.match.func)
})
it('should call callback with the root doc', function(done) {
get.callsArgWithAsync(1, null, rootResponse)
- api.walk().getResource(callback)
+ api.follow().getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -58,7 +58,7 @@ describe('getResource for JSON', function() {
it('should call callback with err', function(done) {
var err = new Error('test error')
get.callsArgWithAsync(1, err)
- api.walk().getResource(callback)
+ api.follow().getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -68,12 +68,12 @@ describe('getResource for JSON', function() {
)
})
- it('should walk a single element path', function(done) {
+ it('should follow a single element path', function(done) {
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponse)
get.withArgs(rootUri + '/link/to/thing',
sinon.match.func).callsArgWithAsync(1, null, result)
- api.walk('link').getResource(callback)
+ api.follow('link').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -83,12 +83,12 @@ describe('getResource for JSON', function() {
)
})
- it('should walk a single element path as array', function(done) {
+ it('should follow a single element path as array', function(done) {
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponse)
get.withArgs(rootUri + '/link/to/thing',
sinon.match.func).callsArgWithAsync(1, null, result)
- api.walk(['link']).getResource(callback)
+ api.follow(['link']).getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -101,7 +101,7 @@ describe('getResource for JSON', function() {
it('should call callback with err if link is not found', function(done) {
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponse)
- api.walk('non-existing-link').getResource(callback)
+ api.follow('non-existing-link').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -121,7 +121,7 @@ describe('getResource for JSON', function() {
1, null, mockResponse({ firstLink: rootUri + '/first' }))
get.withArgs(rootUri + '/first', sinon.match.func).
callsArgWithAsync(1, err)
- api.walk('firstLink').getResource(callback)
+ api.follow('firstLink').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -141,12 +141,12 @@ describe('getResource for JSON', function() {
var result = mockResponse({ the: 'result' })
- it('should walk to a link via JSONPath expression', function(done) {
+ it('should follow to a link via JSONPath expression', function(done) {
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponse)
get.withArgs(uri, sinon.match.func).callsArgWithAsync(1, null,
result)
- api.walk('$.deeply.nested.link').getResource(callback)
+ api.follow('$.deeply.nested.link').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -160,7 +160,7 @@ describe('getResource for JSON', function() {
function(done) {
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponse)
- api.walk('$.deeply.nested.blink').getResource(callback)
+ api.follow('$.deeply.nested.blink').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -180,7 +180,7 @@ describe('getResource for JSON', function() {
})
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponseMulti)
- api.walk('$.arr[*].foo').getResource(callback)
+ api.follow('$.arr[*].foo').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -210,7 +210,7 @@ describe('getResource for JSON', function() {
sinon.match.func).callsArgWithAsync(1, null, next)
get.withArgs(rootUri + '/another/42',
sinon.match.func).callsArgWithAsync(1, null, result)
- api.walk('firstTemplate', 'secondTemplate')
+ api.follow('firstTemplate', 'secondTemplate')
.withTemplateParameters({user: 'basti1302', thing: 4711, id: 42})
.getResource(callback)
waitFor(
@@ -236,7 +236,7 @@ describe('getResource for JSON', function() {
get.withArgs(startUri, sinon.match.func).callsArgWithAsync(
1, null, rootUriTemplate)
- api.walk()
+ api.follow()
.withTemplateParameters({param: 'substituted'})
.getResource(callback)
waitFor(
@@ -262,7 +262,7 @@ describe('getResource for JSON', function() {
sinon.match.func).callsArgWithAsync(1, null, next)
get.withArgs(rootUri + '/another_user/someone_else',
sinon.match.func).callsArgWithAsync(1, null, result)
- api.walk('firstTemplate', 'secondTemplate')
+ api.follow('firstTemplate', 'secondTemplate')
.withTemplateParameters([null,
{user: 'basti1302', thing: 4711},
{user: 'someone_else'}])
@@ -279,7 +279,7 @@ describe('getResource for JSON', function() {
describe('in all its glory', function() {
- it('should walk a multi element path', function(done) {
+ it('should follow a multi element path', function(done) {
var path1 = rootUri + '/path'
var template2 = rootUri + '/path/to/resource{/param}'
var path2 = rootUri + '/path/to/resource/gizmo'
@@ -309,7 +309,7 @@ describe('getResource for JSON', function() {
1, null, response4)
get.withArgs(path4, sinon.match.func).callsArgWithAsync(
1, null, result)
- api.walk(['link1', 'link2', '$[nested][array][1].link', 'link4'])
+ api.follow(['link1', 'link2', '$[nested][array][1].link', 'link4'])
.withTemplateParameters({ param: 'gizmo' })
.getResource(callback)
waitFor(
View
36 test/json_hal.js
@@ -149,7 +149,7 @@ describe('The JSON-HAL walker\'s', function() {
describe('get method', function() {
it('should follow a single link', function(done) {
- api.walk('ea:orders').get(callback)
+ api.follow('ea:orders').get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -160,7 +160,7 @@ describe('The JSON-HAL walker\'s', function() {
})
it('should follow multiple links', function(done) {
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.get(callback)
waitFor(
@@ -174,7 +174,7 @@ describe('The JSON-HAL walker\'s', function() {
it('should pass an embedded document into the callback',
function(done) {
- api.walk('ea:orders', 'ea:order')
+ api.follow('ea:orders', 'ea:order')
.get(callback)
waitFor(
function() { return callback.called },
@@ -189,8 +189,8 @@ describe('The JSON-HAL walker\'s', function() {
)
})
- it('should walk along embedded documents', function(done) {
- api.walk('ea:orders', 'ea:order', 'ea:basket')
+ it('should follow embedded documents', function(done) {
+ api.follow('ea:orders', 'ea:order', 'ea:basket')
.get(callback)
waitFor(
function() { return callback.called },
@@ -205,7 +205,7 @@ describe('The JSON-HAL walker\'s', function() {
describe('getResource method', function() {
it('should return the resource', function(done) {
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.getResource(callback)
waitFor(
@@ -219,7 +219,7 @@ describe('The JSON-HAL walker\'s', function() {
it('should pass an embedded document into the callback',
function(done) {
- api.walk('ea:orders', 'ea:order')
+ api.follow('ea:orders', 'ea:order')
.getResource(callback)
waitFor(
function() { return callback.called },
@@ -234,7 +234,7 @@ describe('The JSON-HAL walker\'s', function() {
describe('getUri method', function() {
it('should return the last URI', function(done) {
- api.walk('ea:orders', 'ea:find')
+ api.follow('ea:orders', 'ea:find')
.withTemplateParameters({ id: 13 })
.getUri(callback)
waitFor(
@@ -248,7 +248,7 @@ describe('The JSON-HAL walker\'s', function() {
// not sure what to do in this case
it('returns the self-URI of an embedded document', function(done) {
- api.walk('ea:orders', 'ea:order')
+ api.follow('ea:orders', 'ea:order')
.getUri(callback)
waitFor(
function() { return callback.called },
@@ -261,7 +261,7 @@ describe('The JSON-HAL walker\'s', function() {
it('yields an error if the last URI is actually an embedded ' +
' resource but has no self-URI', function(done) {
- api.walk('ea:orders', 'ea:find', 'ea:customer', 'ea:no_self_link')
+ api.follow('ea:orders', 'ea:find', 'ea:customer', 'ea:no_self_link')
.withTemplateParameters({ id: 13 })
.getUri(callback)
waitFor(
@@ -285,7 +285,7 @@ describe('The JSON-HAL walker\'s', function() {
executeRequest.withArgs(customerUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, null, updateResponse,
customerUri)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.post(payload, callback)
waitFor(
@@ -305,7 +305,7 @@ describe('The JSON-HAL walker\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(customerUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.post(payload, callback)
waitFor(
@@ -325,7 +325,7 @@ describe('The JSON-HAL walker\'s', function() {
executeRequest.withArgs(customerUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, null, updateResponse,
customerUri)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.put(payload, callback)
waitFor(
@@ -345,7 +345,7 @@ describe('The JSON-HAL walker\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(customerUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.put(payload, callback)
waitFor(
@@ -365,7 +365,7 @@ describe('The JSON-HAL walker\'s', function() {
executeRequest.withArgs(customerUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, null, updateResponse,
customerUri)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.patch(payload, callback)
waitFor(
@@ -385,7 +385,7 @@ describe('The JSON-HAL walker\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(customerUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.patch(payload, callback)
waitFor(
@@ -405,7 +405,7 @@ describe('The JSON-HAL walker\'s', function() {
executeRequest.withArgs(customerUri, sinon.match.func, null,
sinon.match.func).callsArgWithAsync(3, null, updateResponse,
customerUri)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.delete(callback)
waitFor(
@@ -425,7 +425,7 @@ describe('The JSON-HAL walker\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(customerUri, sinon.match.func, null,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('ea:orders', 'ea:find', 'ea:customer')
+ api.follow('ea:orders', 'ea:find', 'ea:customer')
.withTemplateParameters({ id: 13 })
.delete(callback)
waitFor(
View
38 test/json_requests.js
@@ -76,8 +76,8 @@ describe('The JSON client\'s', function() {
describe('get method', function() {
- it('should walk along the links', function(done) {
- api.walk('get_link').get(callback)
+ it('should follow the links', function(done) {
+ api.follow('get_link').get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -94,7 +94,7 @@ describe('The JSON client\'s', function() {
get = sinon.stub()
api.walker.request = { get: get }
get.callsArgWithAsync(1, err)
- api.walk().get(callback)
+ api.follow().get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -114,7 +114,7 @@ describe('The JSON client\'s', function() {
get.withArgs(rootUri, sinon.match.func).callsArgWithAsync(
1, null, rootResponse)
get.withArgs(getUri, sinon.match.func).callsArgWithAsync(1, err)
- api.walk('get_link', 'another_link').get(callback)
+ api.follow('get_link', 'another_link').get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -127,8 +127,8 @@ describe('The JSON client\'s', function() {
})
describe('getUri method', function() {
- it('should walk along the links and yield the last URI', function(done) {
- api.walk('get_link').getUri(callback)
+ it('should follow the links and yield the last URI', function(done) {
+ api.follow('get_link').getUri(callback)
waitFor(
function() { return callback.called },
function() {
@@ -141,7 +141,7 @@ describe('The JSON client\'s', function() {
it('should yield resolved URI if last URI is a URI template',
function(done) {
- api.walk('template_link')
+ api.follow('template_link')
.withTemplateParameters({ param: 'substituted' })
.getUri(callback)
waitFor(
@@ -161,11 +161,11 @@ describe('The JSON client\'s', function() {
var result = mockResponse({ result: 'success' }, 201)
- it('should walk along the links and post to the last URI',
+ it('should follow the links and post to the last URI',
function(done) {
executeRequest.withArgs(postUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, null, result, postUri)
- api.walk('post_link').post(payload, callback)
+ api.follow('post_link').post(payload, callback)
waitFor(
function() { return callback.called },
function() {
@@ -182,7 +182,7 @@ describe('The JSON client\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(postUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('post_link').post(payload, callback)
+ api.follow('post_link').post(payload, callback)
waitFor(
function() { return callback.called },
function() {
@@ -198,11 +198,11 @@ describe('The JSON client\'s', function() {
var result = mockResponse({ result: 'success' }, 200)
- it('should walk along the links and put to the last URI',
+ it('should follow the links and put to the last URI',
function(done) {
executeRequest.withArgs(putUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, null, result, putUri)
- api.walk('put_link').put(payload, callback)
+ api.follow('put_link').put(payload, callback)
waitFor(
function() { return callback.called },
function() {
@@ -219,7 +219,7 @@ describe('The JSON client\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(putUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('put_link').put(payload, callback)
+ api.follow('put_link').put(payload, callback)
waitFor(
function() { return callback.called },
function() {
@@ -234,11 +234,11 @@ describe('The JSON client\'s', function() {
var result = mockResponse({ result: 'success' }, 200)
- it('should walk along the links and patch the last URI',
+ it('should follow the links and patch the last URI',
function(done) {
executeRequest.withArgs(patchUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, null, result, patchUri)
- api.walk('patch_link').patch(payload, callback)
+ api.follow('patch_link').patch(payload, callback)
waitFor(
function() { return callback.called },
function() {
@@ -255,7 +255,7 @@ describe('The JSON client\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(patchUri, sinon.match.func, payload,
sinon.match.func).callsArgWithAsync(3, err, null)
- api.walk('patch_link').patch(payload, callback)
+ api.follow('patch_link').patch(payload, callback)
waitFor(
function() { return callback.called },
function() {
@@ -270,11 +270,11 @@ describe('The JSON client\'s', function() {
var result = mockResponse(null, 204)
- it('should walk along the links and delete the last URI',
+ it('should follow the links and delete the last URI',
function(done) {
executeRequest.withArgs(deleteUri, sinon.match.func, null,
sinon.match.func).callsArgWithAsync(3, null, result, deleteUri)
- api.walk('delete_link').delete(callback)
+ api.follow('delete_link').delete(callback)
waitFor(
function() { return callback.called },
function() {
@@ -291,7 +291,7 @@ describe('The JSON client\'s', function() {
var err = new Error('test error')
executeRequest.withArgs(deleteUri, sinon.match.func, null,
sinon.match.func).callsArgWithAsync(3, err)
- api.walk('delete_link').delete(callback)
+ api.follow('delete_link').delete(callback)
waitFor(
function() { return callback.called },
function() {
View
52 test/localhost.js
@@ -55,7 +55,7 @@ describe('Traverson (when tested against a local server)', function() {
})
it('should fetch the root response', function(done) {
- jsonApi.walk().get(callback)
+ jsonApi.follow().get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -68,7 +68,7 @@ describe('Traverson (when tested against a local server)', function() {
})
it('should fetch the root document', function(done) {
- jsonApi.walk().getResource(callback)
+ jsonApi.follow().getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -80,8 +80,8 @@ describe('Traverson (when tested against a local server)', function() {
)
})
- it('should walk a single element path', function(done) {
- jsonApi.walk('first').getResource(callback)
+ it('should follow a single element path', function(done) {
+ jsonApi.follow('first').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -93,8 +93,8 @@ describe('Traverson (when tested against a local server)', function() {
)
})
- it('should walk a multi-element path', function(done) {
- jsonApi.walk('second', 'doc').get(callback)
+ it('should follow a multi-element path', function(done) {
+ jsonApi.follow('second', 'doc').get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -106,8 +106,8 @@ describe('Traverson (when tested against a local server)', function() {
)
})
- it('should walk a multi-element path in hal+json', function(done) {
- jsonHalApi.walk('first', 'second').get(callback)
+ it('should follow a multi-element path in hal+json', function(done) {
+ jsonHalApi.follow('first', 'second').get(callback)
waitFor(
function() { return callback.called },
function() {
@@ -119,9 +119,9 @@ describe('Traverson (when tested against a local server)', function() {
)
})
- it('should walk a multi-element path in hal+json using an embedded ' +
+ it('should follow a multi-element path in hal+json using an embedded ' +
'resource along the way', function(done) {
- jsonHalApi.walk('first',
+ jsonHalApi.follow('first',
'contained_resource',
'embedded_link_to_second')
.get(callback)
@@ -136,10 +136,10 @@ describe('Traverson (when tested against a local server)', function() {
)
})
- it('should walk a multi-element path in hal+json yielding an embedded ' +
+ it('should follow a multi-element path in hal+json yielding an embedded ' +
'resource to the callback',
function(done) {
- jsonHalApi.walk('first',
+ jsonHalApi.follow('first',
'second',
'inside_second')
.get(callback)
@@ -154,8 +154,8 @@ describe('Traverson (when tested against a local server)', function() {
)
})
- it('should walk a multi-element path to a resource', function(done) {
- jsonApi.walk('second', 'doc').getResource(callback)
+ it('should follow a multi-element path to a resource', function(done) {
+ jsonApi.follow('second', 'doc').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -168,7 +168,7 @@ describe('Traverson (when tested against a local server)', function() {
})
it('should leverage JSONPath', function(done) {
- jsonApi.walk('$.jsonpath.nested.key').getResource(callback)
+ jsonApi.follow('$.jsonpath.nested.key').getResource(callback)
waitFor(
function() { return callback.called },
function() {
@@ -181,7 +181,7 @@ describe('Traverson (when tested against a local server)', function() {
})
it('should leverage URI templates', function(done) {
- jsonApi.walk('uri_template')
+ jsonApi.follow('uri_template')
.withTemplateParameters({param: 'foobar', id: 13})
.getResource(callback)
waitFor(
@@ -197,7 +197,7 @@ describe('Traverson (when tested against a local server)', function() {
})
it('should fail gracefully on 404 with get()', function(done) {