Rest.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
  2. // Note: This doesn't require dojox.rpc.Service, and if you want it you must require it
  3. // yourself, and you must load it prior to dojox.rpc.Rest.
  4. // summary:
  5. // This provides a HTTP REST service with full range REST verbs include PUT,POST, and DELETE.
  6. // description:
  7. // A normal GET query is done by using the service directly:
  8. // | var restService = dojox.rpc.Rest("Project");
  9. // | restService("4");
  10. // This will do a GET for the URL "/Project/4".
  11. // | restService.put("4","new content");
  12. // This will do a PUT to the URL "/Project/4" with the content of "new content".
  13. // You can also use the SMD service to generate a REST service:
  14. // | var services = dojox.rpc.Service({services: {myRestService: {transport: "REST",...
  15. // | services.myRestService("parameters");
  16. //
  17. // The modifying methods can be called as sub-methods of the rest service method like:
  18. // | services.myRestService.put("parameters","data to put in resource");
  19. // | services.myRestService.post("parameters","data to post to the resource");
  20. // | services.myRestService['delete']("parameters");
  21. dojo.getObject("rpc.Rest", true, dojox);
  22. if(dojox.rpc && dojox.rpc.transportRegistry){
  23. // register it as an RPC service if the registry is available
  24. dojox.rpc.transportRegistry.register(
  25. "REST",
  26. function(str){return str == "REST";},
  27. {
  28. getExecutor : function(func,method,svc){
  29. return new dojox.rpc.Rest(
  30. method.name,
  31. (method.contentType||svc._smd.contentType||"").match(/json|javascript/), // isJson
  32. null,
  33. function(id, args){
  34. var request = svc._getRequest(method,[id]);
  35. request.url= request.target + (request.data ? '?'+ request.data : '');
  36. if(args && (args.start >= 0 || args.count >= 0)){
  37. request.headers = request.headers || {};
  38. request.headers.Range = "items=" + (args.start || '0') + '-' +
  39. (("count" in args && args.count != Infinity) ?
  40. (args.count + (args.start || 0) - 1) : '');
  41. }
  42. return request;
  43. }
  44. );
  45. }
  46. }
  47. );
  48. }
  49. var drr;
  50. function index(deferred, service, range, id){
  51. deferred.addCallback(function(result){
  52. if(deferred.ioArgs.xhr && range){
  53. // try to record the total number of items from the range header
  54. range = deferred.ioArgs.xhr.getResponseHeader("Content-Range");
  55. deferred.fullLength = range && (range=range.match(/\/(.*)/)) && parseInt(range[1]);
  56. }
  57. return result;
  58. });
  59. return deferred;
  60. }
  61. drr = dojox.rpc.Rest = function(/*String*/path, /*Boolean?*/isJson, /*Object?*/schema, /*Function?*/getRequest){
  62. // summary:
  63. // Creates a REST service using the provided path.
  64. var service;
  65. // it should be in the form /Table/
  66. service = function(id, args){
  67. return drr._get(service, id, args);
  68. };
  69. service.isJson = isJson;
  70. service._schema = schema;
  71. // cache:
  72. // This is an object that provides indexing service
  73. // This can be overriden to take advantage of more complex referencing/indexing
  74. // schemes
  75. service.cache = {
  76. serialize: isJson ? ((dojox.json && dojox.json.ref) || dojo).toJson : function(result){
  77. return result;
  78. }
  79. };
  80. // the default XHR args creator:
  81. service._getRequest = getRequest || function(id, args){
  82. if(dojo.isObject(id)){
  83. id = dojo.objectToQuery(id);
  84. id = id ? "?" + id: "";
  85. }
  86. if(args && args.sort && !args.queryStr){
  87. id += (id ? "&" : "?") + "sort("
  88. for(var i = 0; i<args.sort.length; i++){
  89. var sort = args.sort[i];
  90. id += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
  91. }
  92. id += ")";
  93. }
  94. var request = {
  95. url: path + (id == null ? "" : id),
  96. handleAs: isJson ? 'json' : 'text',
  97. contentType: isJson ? 'application/json' : 'text/plain',
  98. sync: dojox.rpc._sync,
  99. headers: {
  100. Accept: isJson ? 'application/json,application/javascript' : '*/*'
  101. }
  102. };
  103. if(args && (args.start >= 0 || args.count >= 0)){
  104. request.headers.Range = "items=" + (args.start || '0') + '-' +
  105. (("count" in args && args.count != Infinity) ?
  106. (args.count + (args.start || 0) - 1) : '');
  107. }
  108. dojox.rpc._sync = false;
  109. return request;
  110. };
  111. // each calls the event handler
  112. function makeRest(name){
  113. service[name] = function(id,content){
  114. return drr._change(name,service,id,content); // the last parameter is to let the OfflineRest know where to store the item
  115. };
  116. }
  117. makeRest('put');
  118. makeRest('post');
  119. makeRest('delete');
  120. // record the REST services for later lookup
  121. service.servicePath = path;
  122. return service;
  123. };
  124. drr._index={};// the map of all indexed objects that have gone through REST processing
  125. drr._timeStamps={};
  126. // these do the actual requests
  127. drr._change = function(method,service,id,content){
  128. // this is called to actually do the put, post, and delete
  129. var request = service._getRequest(id);
  130. request[method+"Data"] = content;
  131. return index(dojo.xhr(method.toUpperCase(),request,true),service);
  132. };
  133. drr._get= function(service,id, args){
  134. args = args || {};
  135. // this is called to actually do the get
  136. return index(dojo.xhrGet(service._getRequest(id, args)), service, (args.start >= 0 || args.count >= 0), id);
  137. };
  138. return dojox.rpc.Rest;
  139. });