public
Description: JavaScript Application Framework - JS library only
Home | Edit | New

BitburgerSCRequest

About SC.Request

SC.Request is the new low-level API included with SproutCore to handle Ajax requests. SC.Request is required in order to allow us to be DOM-library independent. However, we’d also like to improve on the basics surrounding Ajax requests since right now the API for managing Ajax requests is pretty hideous.

Status

Some early code has been written for SC.Request but currently no one is working on this. The API defined below needs to be implemented along with unit tests and example code.

Goals and Non-Goals

Specifically, we would like SC.Request to achieve the following:

  • Provide a simple to configure API for building and launching an Ajax request. Use a “builder” or jQuery-like API.
  • Provide queue management for multiple inflight requests. Since browsers limit the number of simultaneous requests, queue management and prioritization will help to avoid browser freezing and UI hicups due to having too many inflight requests.
  • Make a pluggable layer for implementing different transport types. Only XHR will be supported out of the box, but a plugin could be added for json-p, for example.
  • Fixture data for testing. Allow mockup response data and headers to be used in place of making a real connection to the server. Similar to SC.Store fixture support but at a lower level so it exercises more of the code path at the network level. Useful for trying out changes to the data set, debugging captured trace data, and for working offline.
  • Simulate errors for testing. Introduce http errors, latency and timeouts at continuous, periodic or random intervals to simulate real-world conditions. Provides an efficient mechanism to test error handling from the lowest levels all the way up to the UI layers without involving the server.
  • Automated support for caching If a URL has been retrieved before, make sure the headers are properly configured if caching is turned on to use E-tags or If-Modified-Since headers.

SC.Request is a low-level API for making Ajax calls to the server. It is NOT intended as a replacement for SC.Server. (SC.Server would use SC.Request to make requests.) SC.Request should be totally ignorant of the API-backend used.

API Design

SC.Request uses a Builder API to construct a request and send it. Here is the simplest way to send a request:

SC.Request.getUrl(‘/contact/1’).send();

You can use different HTTP methods for the first item:

SC.Request.postUrl(“/contacts/1”).body({ firstName: “Charles”, lastName: “Jolley”, guid: “123” }).send();

Chaining Config Methods

To configure a request, you call the various configuration methods on the request object to set it up. Then call the send() method to actually initiate the request:

SC.Request.getUrl('/contact/1')
  .header('X-Custom-Header', 'Beta')
  .body(someData)
  .params(someParams)
  .notify(target, method)
  .set('async', NO)
  .send();

Sending Requests

You can send a request multiple times simply by calling send(). You can even alter the request config in between calls to send(). This makes it easy to reuse an existing request object as a template instead of having to constantly rebuild your requests from scratch:

var req = SC.Request.getUrl('/twitter/feed').notify(TwitterApp.responseController, 'feedDidRefresh');

  // get feed for user 'okito'
  req.params('user', 'okito').send();

  // get feed for 'sproutit'
  req.params('user', 'sproutit').send();

URL Templates

The URL you specify can actually be a URL template as defined in the Amazon OpenSearch specification. When you call send, you can pass in some parameters that will be interpolated into the URL template. Anything not in the URL template will be appended as params. The example below interpolates the username into the URL:

SC.Request.getUrl(‘/twitter/feed/{Username}’).send({ Username: ‘okito’ });

Observing Requests

SC.Request objects are observable. They have a ‘response’ property that contains either the response from the most recently received request or an Error object if the request failed for some reason. You can use this to construct a controller that triggers whenever a request is sent and received. The example below builds a single request and then triggers the refresh handler:

  Twitter.refreshController = SC.Object.create({

    request: SC.Request.getUrl('/twitter/{Username}.json'),
    
    refresh: function() {
      this.request.send('Username', 'okito');
    },
    
    responseDidChange: function() {
      // handle refrest
    }.observes('.request.response')
    
  }) ;

Overlapping Requests

If you call send() on a Request object before the last request you initiated through the same object has returned, that is called an “overlapping request”. Note that this differs from creating multiple Request objects and sending them. The assumption is that if you are using the same Request object to send a request, you are probably sending the same basic request.

You can determine how the Request object will handle overlapping requests by setting the overlappingRequestPolicy to one of:

  • SC.RESET_REQUEST = cancels the inflight request and issues a new one
  • SC.CANCEL_REQUEST = cancels the new request
  • SC.WAIT_FOR_REQUEST = waits for the previous request to complete, then initiates the new request

Request Formats

SC.Request should support a plugin interface for serializing and deserializing requests. It should provide built-in support for JSON and XML. You should be able to assign a requestFormat property with your preferred format. The response format will always be interpreted using the headers from the response unless you specifically set a responseFormat.

SC.Request.postUrl("/contacts/1")
  .set('requestFormat', SC.XML_FORMAT)
  .body({ testData: "123" }).send();

Still under construction…

Last edited by andyhakim, Mon Dec 08 23:59:10 -0800 2008
Home | Edit | New
Versions: