ModelSync.REST Class
+ + + + +An extension which provides a RESTful XHR sync implementation that can be mixed +into a Model or ModelList subclass.
+ +This makes it trivial for your Model or ModelList subclasses communicate and
+transmit their data via RESTful XHRs. In most cases you'll only need to provide
+a value for root when sub-classing Y.Model.
Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {
+ root: '/users'
+});
+
+Y.Users = Y.Base.create('users', Y.ModelList, [Y.ModelSync.REST], {
+ // By convention Y.User's root will be used for the lists' URL.
+ model: Y.User
+});
+
+var users = new Y.Users();
+
+// GET users list from: "/users"
+users.load(function () {
+ var firstUser = users.item(0);
+
+ firstUser.get('id'); // => "1"
+
+ // PUT updated user data at: "/users/1"
+ firstUser.set('name', 'Eric').save();
+});
+
+-
+
- Index + + +
- Methods + + +
- Properties + + + +
Item Index
+ + +Methods
+ +-
+
+
- + _joinURL + + + + + +
- + _onSyncIOEnd + + + + + +
- + _onSyncIOFailure + + + + + +
- + _onSyncIOStart + + + + + +
- + _onSyncIOSuccess + + + + + +
- + _parse + + + + + +
- + _sendSyncIORequest + + + + + +
- + _substituteURL + + + + + +
- + getURL + + + + + +
- + parseIOResponse + + + + + +
- + serialize + + + + + +
- + sync + + + + + +
Properties
+ +-
+
+
- + _NON_ATTRS_CFG + + + static + + + + +
- + CSRF_TOKEN + + + static + + + + +
- + EMULATE_HTTP + + + static + + + + +
- + HTTP_HEADERS + + + static + + + + +
- + HTTP_METHODS + + + static + + + + +
- + HTTP_TIMEOUT + + + static + + + + +
- + root + + + + + +
- + url + + + + + +
Methods
+ + +_joinURL
+
+
+ -
+
+
-
+
+
url+ +
+
+
Joins the root URL to the specified url, normalizing leading/trailing
+"/" characters.
Parameters:
+ +-
+
+
-
+
+
url+ String + + + + +++ + +URL to append to the
+rootURL.
+
+
Returns:
+ +Example:
+ +model.root = '/foo'
+model._joinURL('bar'); // => '/foo/bar'
+model._joinURL('/bar'); // => '/foo/bar'
+
+model.root = '/foo/'
+model._joinURL('bar'); // => '/foo/bar/'
+model._joinURL('/bar'); // => '/foo/bar/'
+
+ _onSyncIOEnd
+
+
+ -
+
+
-
+
+
txId+ +
+
+ -
+
+
details+ +
+
+
Called when the Y.io request has finished, after "success" or "failure"
+has been determined.
This is a no-op by default, but provides a hook for overriding.
+_onSyncIOFailure
+
+
+ -
+
+
-
+
+
txId+ +
+
+ -
+
+
res+ +
+
+ -
+
+
details+ +
+
+
Called when the Y.io request has finished unsuccessfully.
By default this calls the details.callback function passing it the HTTP
+status code and message as an error object along with the response body.
_onSyncIOStart
+
+
+ -
+
+
-
+
+
txId+ +
+
+ -
+
+
details+ +
+
+ -
+
+
detials.action+ +
+
+
Called when the Y.io request is made.
This is a no-op by default, but provides a hook for overriding.
+_onSyncIOSuccess
+
+
+ -
+
+
-
+
+
txId+ +
+
+ -
+
+
res+ +
+
+ -
+
+
details+ +
+
+
Called when the Y.io request has finished successfully.
By default this calls the details.callback function passing it the
+response body.
_parse
+
+
+ -
+
+
-
+
+
response+ +
+
+
Calls both public, overrideable methods: parseIOResponse(), then parse()
+and returns the result.
This will call into parseIOResponse(), if it's defined as a method,
+passing it the full response object from the XHR and using its return value
+to pass along to the parse(). This enables developers to easily parse data
+out of the response headers which should be used by the parse() method.
Parameters:
+ +-
+
+
-
+
+
response+ Object + + + + +++ + +Response object from
+Y.io().
+
+
_sendSyncIORequest
+
+
+ -
+
+
-
+
+
config+ +
+
+
Performs the XHR and returns the resulting Y.io() request object.
This method is called by sync().
Parameters:
+ +-
+
+
-
+
+
config+ Object + + + + +++ + +An object with the following properties:
+-
+
+
-
+
+
action+ String + + +++ + +The
+sync()action being performed.
+
+ -
+
+
[callback]+ Function + optional + + +++ + +Called when the sync operation + finishes.
+
+
+ -
+
+
[entity]+ String + optional + + +++ + +The HTTP request entity body.
+
+
+ -
+
+
headers+ Object + + +++ + +The HTTP request headers.
+
+
+ -
+
+
method+ String + + +++ + +The HTTP request method.
+
+
+ -
+
+
[timeout]+ Number + optional + + +++ + +Time until the HTTP request is aborted.
+
+
+ -
+
+
url+ String + + +++ + +The URL of the HTTP resource.
+
+
+
+
+ -
+
+
Returns:
+ +Y.io() request object.
+
+ _substituteURL
+
+
+ -
+
+
-
+
+
url+ +
+
+ -
+
+
data+ +
+
+
Utility which takes a tokenized url string and substitutes its
+placeholders using a specified data object.
This method will property URL-encode any values before substituting them. +Also, only expect it to work with String and Number values.
+Parameters:
+ + +Returns:
+ +Example:
+ +var url = this._substituteURL('/users/{name}', {id: 'Eric F'});
+// => "/users/Eric%20F"
+
+ getURL
+
+
+ -
+
+
-
+
+
[action]+ +
+
+ -
+
+
[options]+ +
+
+
Returns the URL for this model or model list for the given action and
+options, if specified.
This method correctly handles the variations of root and url values and
+is called by the sync() method to get the URLs used to make the XHRs.
You can override this method if you need to provide a specific +implementation for how the URLs of your Model and ModelList subclasses need +to be generated.
+Parameters:
+ + +Returns:
+ + +parseIOResponse
+
+
+ -
+
+
-
+
+
response+ +
+
+
Called to parse the response object returned from Y.io(). This method
+receives the full response object and is expected to "prep" a response which
+is suitable to pass to the parse() method.
By default the response body is returned (responseText), because it
+usually represents the entire entity of this model on the server.
If you need to parse data out of the response's headers you should do so by
+overriding this method. If you'd like the entire response object from the
+XHR to be passed to your parse() method, you can simply assign this
+property to false.
Parameters:
+ +-
+
+
-
+
+
response+ Object + + + + +++ + +Response object from
+Y.io().
+
+
Returns:
+ +parse() method.
+
+ serialize
+
+
+ -
+
+
-
+
+
[action]+ +
+
+
Serializes this model to be used as the HTTP request entity body.
By default this model will be serialized to a JSON string via its toJSON()
+method.
You can override this method when the HTTP server expects a different
+representation of this model's data that is different from the default JSON
+serialization. If you're sending and receive content other than JSON, be
+sure change the Accept and Content-Type HTTP_HEADERS as well.
Note: A model's toJSON() method can also be overridden. If you only
+need to modify which attributes are serialized to JSON, that's a better
+place to start.
Parameters:
+ +-
+
+
-
+
+
[action]+ String + optional + + + + +++ + +Optional
+sync()action for which to generate the + the serialized representation of this model.
+
+
Returns:
+ +sync
+
+
+ -
+
+
-
+
+
action+ +
+
+ -
+
+
[options]+ +
+
+ -
+
+
[callback]+ +
+
+
Communicates with a RESTful HTTP server by sending and receiving data via +XHRs. This method is called internally by load(), save(), and destroy().
+ +The URL used for each XHR will be retrieved by calling the getURL() method
+and passing it the specified action and options.
This method relies heavily on standard RESTful HTTP conventions
+Parameters:
+ +-
+
+
-
+
+
action+ String + + + + +++ + +Sync action to perform. May be one of the following:
+ +-
+
create: Store a newly-created model for the first time.
+delete: Delete an existing model.
+read: Load an existing model.
+update: Update an existing model.
+
+
+ -
+
+
[options]+ Object + optional + + + + +++ + +Sync options:
+-
+
+
-
+
+
[csrfToken]+ String + optional + + +++ + +The authenticity token used by the + server to verify the validity of this request and protected against CSRF + attacks. This overrides the default value provided by the static +
+CSRF_TOKENproperty.
+
+ -
+
+
[headers]+ Object + optional + + +++ + +The HTTP headers to mix with the default + headers specified by the static
+HTTP_HEADERSproperty.
+
+ -
+
+
[timeout]+ Number + optional + + +++ + +The number of milliseconds before the + request will timeout and be aborted. This overrides the default provided + by the static
+HTTP_TIMEOUTproperty.
+
+
+
+ -
+
+
-
+
+
[callback]+ Function + optional + + + + +++ + +Called when the sync operation finishes.
+-
+
+
-
+
+
err+ Error | Null + + +++ + +If an error occurred, this parameter will + contain the error. If the sync operation succeeded, err will be + falsy.
+
+
+ -
+
+
[response]+ Any + optional + + +++ + +The server's response.
+
+
+
+
+ -
+
+
Properties
+ + +_NON_ATTRS_CFG
+ Array
+
+
+
+
+ protected
+
+
+
+
+
+ static
+
+
+
+
+ Properties that shouldn't be turned into ad-hoc attributes when passed to a +Model or ModelList constructor.
+Default: ["root", "url"]
+ + + + + +CSRF_TOKEN
+ String
+
+
+
+
+
+
+
+
+ static
+
+
+
+
+ A request authenticity token to validate HTTP requests made by this extension +with the server when the request results in changing persistent state. This +allows you to protect your server from Cross-Site Request Forgery attacks.
+ +A CSRF token provided by the server can be embedded in the HTML document and
+assigned to YUI.Env.CSRF_TOKEN like this:
<script>
+ YUI.Env.CSRF_TOKEN = {{session.authenticityToken}};
+</script>
+
+
+The above should come after YUI seed file so that YUI.Env will be defined.
Note: This can be overridden on a per-request basis. See sync() method.
When a value for the CSRF token is provided, either statically or via options
+passed to the save() and destroy() methods, the applicable HTTP requests
+will have a X-CSRF-Token header added with the token value.
Default: YUI.Env.CSRF_TOKEN
+ + + + + +EMULATE_HTTP
+ Boolean
+
+
+
+
+
+
+
+
+ static
+
+
+
+
+ Static flag to use the HTTP POST method instead of PUT or DELETE.
+ +If the server-side HTTP framework isn't RESTful, setting this flag to true
+will cause all PUT and DELETE requests to instead use the POST HTTP method, and
+add a X-HTTP-Method-Override HTTP header with the value of the method type
+which was overridden.
Default: false
+ + + + + +HTTP_HEADERS
+ Object
+
+
+
+
+
+
+
+
+ static
+
+
+
+
+ Default headers used with all XHRs.
+ +By default the Accept and Content-Type headers are set to
+"application/json", this signals to the HTTP server to process the request
+bodies as JSON and send JSON responses. If you're sending and receiving content
+other than JSON, you can override these headers and the parse() and
+serialize() methods.
Note: These headers will be merged with any request-specific headers, and +the request-specific headers will take precedence.
+Default: { + "Accept" : "application/json", + "Content-Type": "application/json" + }
+ + + + + +HTTP_METHODS
+ Object
+
+
+
+
+
+
+
+
+ static
+
+
+
+
+ Static mapping of RESTful HTTP methods corresponding to CRUD actions.
+Default: { + "create": "POST", + "read" : "GET", + "update": "PUT", + "delete": "DELETE" + }
+ + + + + +HTTP_TIMEOUT
+ Number
+
+
+
+
+
+
+
+
+ static
+
+
+
+
+ The number of milliseconds before the XHRs will timeout/abort. This defaults to +30 seconds.
+ +Note: This can be overridden on a per-request basis. See sync() method.
Default: 30000
+ + + + + +root
+ String
+
+
+
+
+
+
+
+
+
+
+
+ A string which represents the root or collection part of the URL which +relates to a Model or ModelList. Usually this value should be same for all +instances of a specific Model/ModelList subclass.
+ +When sub-classing Y.Model, usually you'll only need to override this
+property, which lets the URLs for the XHRs be generated by convention. If
+the root string ends with a trailing-slash, XHR URLs will also end with a
+"/", and if the root does not end with a slash, neither will the XHR URLs.
Default: ""
+ + + +Example:
+ +Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {
+ root: '/users'
+});
+
+var currentUser, newUser;
+
+// GET the user data from: "/users/123"
+currentUser = new Y.User({id: '123'}).load();
+
+// POST the new user data to: "/users"
+newUser = new Y.User({name: 'Eric Ferraiuolo'}).save();
+
+
+When sub-classing Y.ModelList, usually you'll want to ignore configuring
+the root and simply rely on the build-in convention of the list's
+generated URLs defaulting to the root specified by the list's model.
url
+ String
+
+
+
+
+
+
+
+
+
+
+
+ A string which specifies the URL to use when making XHRs, if not value is +provided, the URLs used to make XHRs will be generated by convention.
+ +While a url can be provided for each Model/ModelList instance, usually
+you'll want to either rely on the default convention or provide a tokenized
+string on the prototype which can be used for all instances.
When sub-classing Y.Model, you will probably be able to rely on the
+default convention of generating URLs in conjunction with the root
+property and whether the model is new or not (i.e. has an id). If the
+root property ends with a trailing-slash, the generated URL for the
+specific model will also end with a trailing-slash.
Default: ""
+ + + +Example:
+ +Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {
+ root: '/users/'
+});
+
+var currentUser, newUser;
+
+// GET the user data from: "/users/123/"
+currentUser = new Y.User({id: '123'}).load();
+
+// POST the new user data to: "/users/"
+newUser = new Y.User({name: 'Eric Ferraiuolo'}).save();
+
+
+If a url is specified, it will be processed by Y.Lang.sub(), which is
+useful when the URLs for a Model/ModelList subclass match a specific pattern
+and can use simple replacement tokens; e.g.:
Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {
+ root: '/users',
+ url : '/users/{username}'
+});
+
+
+Note: String subsitituion of the url only use string an number values
+provided by this object's attribute and/or the options passed to the
+getURL() method. Do not expect something fancy to happen with Object,
+Array, or Boolean values, they will simply be ignored.
If your URLs have plural roots or collection URLs, while the specific item
+resources are under a singular name, e.g. "/users" (plural) and "/user/123"
+(singular), you'll probably want to configure the root and url
+properties like this:
Y.User = Y.Base.create('user', Y.Model, [Y.ModelSync.REST], {
+ root: '/users',
+ url : '/user/{id}'
+});
+
+var currentUser, newUser;
+
+// GET the user data from: "/user/123"
+currentUser = new Y.User({id: '123'}).load();
+
+// POST the new user data to: "/users"
+newUser = new Y.User({name: 'Eric Ferraiuolo'}).save();
+
+
+When sub-classing Y.ModelList, usually you'll be able to rely on the
+associated model to supply its root to be used as the model list's URL.
+If this needs to be customized, you can provide a simple string for the
+url property.
Y.Users = Y.Base.create('users', Y.ModelList, [Y.ModelSync.REST], {
+ // Leverages Y.User's root, which is "/users".
+ model: Y.User
+});
+
+// Or specified explicitly...
+
+Y.Users = Y.Base.create('users', Y.ModelList, [Y.ModelSync.REST], {
+ model: Y.User,
+ url : '/users'
+});
+
+ 