JsonRest.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. define("dojo/store/JsonRest", ["../_base/xhr", "../json", "../_base/declare", "./util/QueryResults"
  2. ], function(xhr, JSON, declare, QueryResults) {
  3. // module:
  4. // dojo/store/JsonRest
  5. // summary:
  6. // The module defines a JSON/REST based object store
  7. return declare("dojo.store.JsonRest", null, {
  8. // summary:
  9. // This is a basic store for RESTful communicating with a server through JSON
  10. // formatted data. It implements dojo.store.api.Store.
  11. constructor: function(/*dojo.store.JsonRest*/ options){
  12. // summary:
  13. // This is a basic store for RESTful communicating with a server through JSON
  14. // formatted data.
  15. // options:
  16. // This provides any configuration information that will be mixed into the store
  17. declare.safeMixin(this, options);
  18. },
  19. // target: String
  20. // The target base URL to use for all requests to the server. This string will be
  21. // prepended to the id to generate the URL (relative or absolute) for requests
  22. // sent to the server
  23. target: "",
  24. // idProperty: String
  25. // Indicates the property to use as the identity property. The values of this
  26. // property should be unique.
  27. idProperty: "id",
  28. // sortParam: String
  29. // The query parameter to used for holding sort information. If this is omitted, than
  30. // the sort information is included in a functional query token to avoid colliding
  31. // with the set of name/value pairs.
  32. get: function(id, options){
  33. // summary:
  34. // Retrieves an object by its identity. This will trigger a GET request to the server using
  35. // the url `this.target + id`.
  36. // id: Number
  37. // The identity to use to lookup the object
  38. // returns: Object
  39. // The object in the store that matches the given id.
  40. var headers = options || {};
  41. headers.Accept = this.accepts;
  42. return xhr("GET", {
  43. url:this.target + id,
  44. handleAs: "json",
  45. headers: headers
  46. });
  47. },
  48. // accepts: String
  49. // Defines the Accept header to use on HTTP requests
  50. accepts: "application/javascript, application/json",
  51. getIdentity: function(object){
  52. // summary:
  53. // Returns an object's identity
  54. // object: Object
  55. // The object to get the identity from
  56. // returns: Number
  57. return object[this.idProperty];
  58. },
  59. put: function(object, options){
  60. // summary:
  61. // Stores an object. This will trigger a PUT request to the server
  62. // if the object has an id, otherwise it will trigger a POST request.
  63. // object: Object
  64. // The object to store.
  65. // options: dojo.store.api.Store.PutDirectives?
  66. // Additional metadata for storing the data. Includes an "id"
  67. // property if a specific id is to be used.
  68. // returns: Number
  69. options = options || {};
  70. var id = ("id" in options) ? options.id : this.getIdentity(object);
  71. var hasId = typeof id != "undefined";
  72. return xhr(hasId && !options.incremental ? "PUT" : "POST", {
  73. url: hasId ? this.target + id : this.target,
  74. postData: JSON.stringify(object),
  75. handleAs: "json",
  76. headers:{
  77. "Content-Type": "application/json",
  78. Accept: this.accepts,
  79. "If-Match": options.overwrite === true ? "*" : null,
  80. "If-None-Match": options.overwrite === false ? "*" : null
  81. }
  82. });
  83. },
  84. add: function(object, options){
  85. // summary:
  86. // Adds an object. This will trigger a PUT request to the server
  87. // if the object has an id, otherwise it will trigger a POST request.
  88. // object: Object
  89. // The object to store.
  90. // options: dojo.store.api.Store.PutDirectives?
  91. // Additional metadata for storing the data. Includes an "id"
  92. // property if a specific id is to be used.
  93. options = options || {};
  94. options.overwrite = false;
  95. return this.put(object, options);
  96. },
  97. remove: function(id){
  98. // summary:
  99. // Deletes an object by its identity. This will trigger a DELETE request to the server.
  100. // id: Number
  101. // The identity to use to delete the object
  102. return xhr("DELETE",{
  103. url:this.target + id
  104. });
  105. },
  106. query: function(query, options){
  107. // summary:
  108. // Queries the store for objects. This will trigger a GET request to the server, with the
  109. // query added as a query string.
  110. // query: Object
  111. // The query to use for retrieving objects from the store.
  112. // options: dojo.store.api.Store.QueryOptions?
  113. // The optional arguments to apply to the resultset.
  114. // returns: dojo.store.api.Store.QueryResults
  115. // The results of the query, extended with iterative methods.
  116. var headers = {Accept: this.accepts};
  117. options = options || {};
  118. if(options.start >= 0 || options.count >= 0){
  119. headers.Range = "items=" + (options.start || '0') + '-' +
  120. (("count" in options && options.count != Infinity) ?
  121. (options.count + (options.start || 0) - 1) : '');
  122. }
  123. if(query && typeof query == "object"){
  124. query = xhr.objectToQuery(query);
  125. query = query ? "?" + query: "";
  126. }
  127. if(options && options.sort){
  128. var sortParam = this.sortParam;
  129. query += (query ? "&" : "?") + (sortParam ? sortParam + '=' : "sort(");
  130. for(var i = 0; i<options.sort.length; i++){
  131. var sort = options.sort[i];
  132. query += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
  133. }
  134. if(!sortParam){
  135. query += ")";
  136. }
  137. }
  138. var results = xhr("GET", {
  139. url: this.target + (query || ""),
  140. handleAs: "json",
  141. headers: headers
  142. });
  143. results.total = results.then(function(){
  144. var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
  145. return range && (range=range.match(/\/(.*)/)) && +range[1];
  146. });
  147. return QueryResults(results);
  148. }
  149. });
  150. });