Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit f731eddabd435c1d57903bb7269d14029a511adb @scothis scothis committed May 23, 2012
Showing with 2,186 additions and 0 deletions.
  1. +8 −0 .gitignore
  2. +24 −0 LICENSE.txt
  3. +146 −0 README.md
  4. +35 −0 package.json
  5. +50 −0 src/rest.js
  6. +133 −0 src/rest/UrlBuilder.js
  7. +91 −0 src/rest/client/xhr.js
  8. +75 −0 src/rest/interceptor/_base.js
  9. +39 −0 src/rest/interceptor/basicAuth.js
  10. +31 −0 src/rest/interceptor/entity.js
  11. +35 −0 src/rest/interceptor/errorCode.js
  12. +73 −0 src/rest/interceptor/mime.js
  13. +157 −0 src/rest/interceptor/oAuth.js
  14. +50 −0 src/rest/interceptor/pathPrefix.js
  15. +112 −0 src/rest/mime/registry.js
  16. +15 −0 src/rest/mime/type/application/html.js
  17. +24 −0 src/rest/mime/type/application/json.js
  18. +14 −0 src/rest/mime/type/text/html.js
  19. +24 −0 src/rest/mime/type/text/plain.js
  20. +165 −0 src/rest/util/base64.js
  21. +38 −0 src/rest/util/beget.js
  22. +50 −0 src/rest/util/mixin.js
  23. +34 −0 src/rest/util/normalizeHeaderName.js
  24. +51 −0 src/rest/util/pubsub.js
  25. +55 −0 test/UrlBuilder-test.js
  26. +37 −0 test/buster.js
  27. +47 −0 test/client/xhr-test-browser.js
  28. +48 −0 test/interceptor/basicAuth-test.js
  29. +40 −0 test/interceptor/entity-test.js
  30. +60 −0 test/interceptor/errorCode-test.js
  31. +45 −0 test/interceptor/mime-test.js
  32. +68 −0 test/interceptor/oAuth-test.js
  33. +50 −0 test/interceptor/pathPrefix-test.js
  34. +55 −0 test/mime/registry-test.js
  35. +20 −0 test/mime/type/application/json-test.js
  36. +23 −0 test/mime/type/text/plain-test.js
  37. +20 −0 test/util/base64-test.js
  38. +41 −0 test/util/beget-test.js
  39. +36 −0 test/util/mixin-test.js
  40. +20 −0 test/util/normalizeHeaderName-test.js
  41. +47 −0 test/util/pubsub-test.js
@@ -0,0 +1,8 @@
+.DS_Store
+.buildpath
+.classpath
+.idea
+.project
+.settings
+/node_modules
+/npm-debug.log
@@ -0,0 +1,24 @@
+Open Source Initiative OSI - The MIT License
+
+http://www.opensource.org/licenses/mit-license.php
+
+Copyright (c) 2012 the original authors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
146 README.md
@@ -0,0 +1,146 @@
+Rest Template
+=============
+
+...in progress...
+
+
+Getting Started
+---------------
+
+Rest can be installed via NPM, or from source.
+
+To install without source:
+
+ $ npm install rest-template
+
+From source:
+
+ $ npm install
+
+Rest is designed to run in a browser environment, utilizing AMD modules, or within Node.js. [curl](https://github.com/cujojs/curl) is highly recommended as an AMD loader, although any loader should work.
+
+An ECMAScript 5 compatible environment is assumed. Older browsers that do not support ES5 natively can be shimmed. Any shim should work, although we've tested against cujo's [poly](https://github.com/cujojs/poly)
+
+
+Usage
+-----
+
+Using Rest is easy. The core clients provide limited functionality around the request and response lifecycle. The input and response objects are normalized to support portability between browser and server environments.
+
+The response from a client is a promise that will be resolved when the remote request is finished.
+
+The core client behavior can be augmented with interceptors. An interceptor wraps the client and transforms the request and response. For example: an interceptor may authenticate a request, or reject the promise if an error is encountered. Interceptors may be combined to create a client with the desired behavior. A configured interceptor acts just like a client.
+
+
+### Making a basic request: ###
+
+ define(['rest'], function(client) {
+ client({ path: '/' }).then(function(response) {
+ console.log('response: ', response);
+ });
+ });
+
+In this example, you can see that the request object is very simple, it just includes the path. All of the attributes of a request are optional.
+
+The response should look familiar as well, it contains all the fields you would expect, including the response headers (many clients ignore the headers).
+
+
+### Working with JSON: ###
+
+If you're paying attention, you may have noticed that the response.entity in the previous example is a String. Often we need to work with more complex data types. For this, Rest supports a rich set of MIME type conversions with the `mime` interceptor. The correct converter will automatically be chosen based on the Content-Type response header. Custom converts can be registered for a MIME type, more on that later...
+
+ define(['rest/interceptor/mime'], function(mime) {
+ var client = mime();
+ client({ path: '/data.json' }).then(function(response) {
+ console.log('response: ', response);
+ });
+ });
+
+Before an interceptor can be used, it needs to be configured. In this case, we will accept the default configuration, and obtain a client. Now when we see the response, the entity will be a JS object instead of a String.
+
+
+### Composing Interceptors: ###
+
+ define(['rest/interceptor/mime', 'rest/interceptor/errorCode'], function(mime, errorCode) {
+ var client = mime();
+ client = errorCode(client, { code: 500 });
+ client({ path: '/data.json' }).then(
+ function(response) {
+ console.log('response: ', response);
+ },
+ function(response) {
+ console.error('response error: ', response);
+ }
+ );
+ });
+
+In this example, we take the client create by the `mime` interceptor, and wrap it in the `errorCode` interceptor. The errorCode interceptor can accept a configuration object that indicates what status codes should be considered an error. In this case we override the default value of <=400, to only reject with 500 or greater status code.
+
+Since the errorCode interceptor can reject the response promise, we also add a second handler function to receive the response for requests in error.
+
+Clients can continue to be composed with interceptors as needed. At any point the client as configured can be shared. It is safe to share clients and allow other parts of your application to continue to compose other clients around the shared core. Your client is protected from additional interceptors that other parts of the application may add.
+
+
+### Custom MIME Converters: ###
+
+ define(['rest/mime/registry'], function(registry) {
+ registry.register('application/vnd.com.example', {
+ read: function(str) {
+ var obj = str;
+ // do string to object conversions
+ return obj;
+ },
+ write: function(obj) {
+ var str = obj;
+ // do object to string conversions
+ return str;
+ }
+ });
+ });
+
+Registering a custom converter is a simple as calling the register function on the mime registry with the type and converter. A converter has just two methods: `read` and `write`. Read converts a String to a more complex Object. Write converts an Object back into a String to be sent to the server. HTTP is fundamentally a text based protocol after all.
+
+Built in converters are available under `rest/mime/type/{type}`, as an example, JSON support is located at `rest/mime/type/application/json`. You never need to know this as a consumer, but it's a good place to find examples.
+
+
+Reporting Issues
+----------------
+
+Please report issues on [GitHub](https://github.com/scothis/rest/issues). Include a brief description of the error, detailed information about the runtime (including shims) and any error messages.
+
+Feature requests are also welcome.
+
+
+Running the Tests
+-----------------
+
+The test suite can be run in two different modes: in node, or in a browser. We use Buster.JS as the test harness, buster will be installed by npm for the node tests. For browser tests, you may need to run `npm install -g buster` to make the buster commands available.
+
+To run the suite in node:
+
+ $ npm test
+
+To run the suite in a browser:
+
+ $ buster server &
+ browse to http://localhost:1111/capture in the browser(s) you wish to test, tests can be run concurrently across multiple browsers
+
+ $ buster test -e browser
+
+ kill the server process or keep it in the background for further test runs
+
+
+Thanks
+------
+
+* Arjen Poutsma - Creator of Spring's RestTemplate
+* Brian Cavalier - cujo.js lead
+* John Hann - cujo.js lead
+* VMware - for allowing this project to be open sourced
+
+
+Change Log
+----------
+
+No releases yet, soon
+
@@ -0,0 +1,35 @@
+{
+ "name": "rest-template",
+ "version": "0.0.1",
+ "description": "HTTP client library inspired by the Spring Framework's RestTemplate",
+ "keywords": ["rest", "http", "client", "rest-template", "spring"],
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://www.opensource.org/licenses/mit-license.php"
+ }
+ ],
+ "repositories": [
+ {
+ "type": "git",
+ "url": "https://github.com/scothis/rest"
+ }
+ ],
+ "bugs": "https://github.com/scothis/rest/issues",
+ "maintainers": [
+ {
+ "name": "Scott Andrews",
+ "web": "http://twitter.com/scothis"
+ }
+ ],
+ "dependencies": {
+ "when": "https://github.com/cujojs/when/tarball/1.1.1"
+ },
+ "devDependencies": {
+ "buster": "~0.5"
+ },
+ "main": "./src/rest",
+ "scripts": {
+ "test": "buster test -e node"
+ }
+}
@@ -0,0 +1,50 @@
+(function(define) {
+
+// TODO use has! to choose the appropriate client impl
+define(['./rest/client/xhr'], function(client){
+
+ /**
+ * Plain JS Object containing properties that represent an HTTP request
+ *
+ * @field {String} [method='GET'] HTTP method, commonly GET, POST, PUT, DELETE or HEAD
+ * @field {String|UrlBuilder} [path=''] path template with optional path variables
+ * @field {Object} [params] parameters for the path template and query string
+ * @field {Object} [headers] custom HTTP headers to send, in addition to the clients default headers
+ * @field {*} [entity] the HTTP entity, common for POST or PUT requests
+ *
+ * @class Request
+ */
+
+ /**
+ * Plain JS Object containing properties that represent an HTTP response
+ *
+ * @field {Object} [request] the request object as received by the root client
+ * @field {Object} [raw] the underlying request object, like XmlHttpRequest in a browser
+ * @field {Number} [status.code] status code of the response (i.e. 200, 404)
+ * @field {String} [status.text] status phrase of the response
+ * @field {Object] [headers] response headers hash of normalized name, value pairs
+ * @field {*} [entity] the response body
+ *
+ * @class Response
+ */
+
+ /**
+ * HTTP client particularly suited for RESTful operations.
+ *
+ * @param {Request} the HTTP request
+ * @returns {Promise<Response>} a promise the resolves to the HTTP response
+ *
+ * @class Client
+ */
+
+ return client;
+});
+
+})(typeof define == 'function'
+ ? define
+ : function(deps, factory) { typeof module != 'undefined'
+ ? (module.exports = factory.apply(this, deps.map(require)))
+ : (this.rest = factory(this.rest_client_xhr));
+ }
+ // Boilerplate for AMD, Node, and browser global
+);
Oops, something went wrong.

0 comments on commit f731edd

Please sign in to comment.