حنیف شیخ عبدالکریم-Hanif sheikhabdolkarim
Contact me
My Profile
Blog Author(s) حنیف شیخ عبدالکریم-Hanif sheikhabdolkarim
Previous Months Home Archive ۱۳٩٠/۱۱/۸ ۱۳٩٠/۱/٢٧ ۱۳۸٩/۱٢/۱٤ ۱۳۸٩/۱٢/٧ ۱۳۸٩/۱۱/٢۳ More ...
      فن آوری اطلاعات و مدیریت -- ICT (ICT -Managment-High Tech)
datajs - JavaScript Library for data-centric web applications by: حنیف شیخ عبدالکریم-Hanif sheikhabdolkarim

Contents

  1. datajs Overview
  2. API Documentation
    1. read
    2. request
    3. defaultSuccess
    4. defaultError
    5. defaultHttpClient
  3. OData
    1. OData code snippets
    2. Metadata
    3. Security
    4. Cross-domain requests
    5. OData internals

datajs Overview

datajs is a cross-browser JavaScript library that supports data-centric web applications by leveraging modern protocols and browser features. It's designed to be small, fast, and provide functionality that makes web applications first-class citizens of web data.

Currently the library offers functionality to communicate with OData services. If you're not familiar with OData, there are good resources for learning at http://www.odata.org/developers.

The library supports receiving data and submitting changes or invoking service operations. The API can be made aware of metadata in cases where it's required, and operations can be batched to minimize round-trips.

We plan to extend the level of functionality in this area, as well as providing APIs to work with local data through browser features such as IndexedDB as they become available in popular browsers.

API Documentation

OData.read

Description: Reads data from the specified URL.

OData.read = function (url | request, [success(data, response)], [error(error)], [handler], [httpClient], [metadata])

Parameters

url - A string containing the URL to which the request is sent.

request -  An Object that represents the HTTP request to be sent.

success(data, response) - A callback function that is executed if the request succeeds, taking the processed data and the server response.

error(error) - A callback function that is executed if the request fails, taking an error object.

handler - Handler object for the response data.

httpClient - Object to use as an HTTP stack.

metadata - Object describing the structural metadata to use.

Details

This function is used to read data from an OData end point. In its simplest form this function takes a URL string to which an HTTP GET request is sent.

For example you can get all available Genres in the Netflix service by making the following call.

OData.read("http://odata.netflix.com/v1/Catalog/Genres");

As part of the URI you can also pass in parameters.

OData.read("http://odata.netflix.com/v1/Catalog/Genres?$top=3");

For full documentation on OData supported URIs refer to the OData documentation on the OData site.

The success parameter of the read operation takes a callback function, which is executed if the request succeeds. If it is not defined then the default success handler is used from OData.defaultSuccess, which simply shows a dialog box with the results in a string form. It is a good practice to define your own success callback function.

OData.read("http://odata.netflix.com/v1/Catalog/Genres",
function (data, request) {
var html = "";
for (var i = 0; i < data.length; i++) {
html += "<div>" + data[i].Name + "</div>";
}
document.getElementById("target-element-id").innerHTML = html;
});

The read function also takes an error parameter which is a callback function. The error callback is executed if the request fails. If the function is not defined then the default error handler OData.defaultError is invoked causing the error to be thrown as an exception.

OData.read("http://odata.netflix.com/v1/Catalog/Genres",
function (data, request) {
var html = "";
for (var i = 0; i < data.length; i++) {
html += "<div>" + data[i].Name + "</div>";
}
document.getElementById("target-element-id").innerHTML = html;
}, function(err){
alert("Error occurred " + err.message);
});

A handler can optionally be passed to the OData.read function. By default the MIME-based handler is used, which looks at the Content-Type header and uses the correct handler to parse the payload results. For example if the response's content type header is application/json then the JSON handler would be invoked to parse the data.

The read function also takes in an httpClient object. If it is not defined then the default httpClient object is used from OData.defaultHttpClient, which is set to a library that can take an HTTP request representation and return a response message from it.

More information on how to define a custom handler and httpClient is covered under handler and httpClient documentation respectively.

The metadata parameter is optional, and defaults to OData.defaultMetadata. Handlers make use of metadata to enhance how they process data.

To allow finer control over what is sent in the request this function also allows passing in a request object instead of a simple URI string.

The following example shows how to specify the accept type inside the request object, along with success and error callback functions.

OData.read({ requestUri: "http://odata.netflix.com/v1/Catalog/Genres",
headers: { Accept: "application/json" } },
function (data, response) {
alert("Operation succeeded.");
}, function (err) {
alert("Error occurred " + err.message);
});

The read operation returns a request value. The request value supports an abort invocation to cancel progress.


Top

 

OData.request

Description: Sends a request containing OData payload to the server.

Odata.request = function (request, [success(data, response)], [error(error)], [handler], [httpClient], [metadata])

 Parameters

request - An Object that represents the HTTP request to be sent

success(data, response) - A callback function that is executed if the request succeeds, taking the processed data and the server response.

error(error)  - A callback function that is executed if the request fails, taking an error object.

handler - Handler object for the request data.

httpClient - Object to use as an HTTP stack.

metadata - Object describing the structural metadata to use.

Details

The OData.request is a low level API for fine grained control over the request. It provides optional parameters to set callback functions, custom data handler and the HTTP client to use.

This API takes a request object as the first parameter that contains the headers, the target URI, the HTTP verb, which defines which CRUD operation to perform, and lastly the data on which the action takes place.

The request object should conform to the following signature:

request = { 
headers : object, // object that contains HTTP headers as name value pairs
requestUri : string, // OData endpoint URI
method : string, // HTTP method (GET, POST, PUT, DELETE)
data : object // Payload of the request (in intermediate format)
};

The headers is an object containing key value pairs that let the user control the semantics of the HTTP request. For example user can specify the 'Accept' type for data or the version of the DataService. Whatever is defined in the headers object takes precedence over the defaults; however if a value is missing in the headers then the defaults are used. For example if the caller specifies a given DataServiceVersion, then handlers will not set the value for the DataServiceVersion header.

var request = { headers : { "DataServiceVersion": "2.0" } };

The requestUri is a string value that specifies the location on the OData endpoint to which the operation is targeted. For operations on existing items the URI should resolve to a single entity or link. For an insert operation this URI points to the resource set or collection to which the entity is inserted. For more information on OData operations refer to: http://www.odata.org/developers/protocols/operations

Here are few examples of how the requestUri would look for a given operation.

Add a new entity in an entity set
requestUri : http://services.odata.org/website/odata.svc/Customers

Add a new entity in a linked entity set
requestUri : http://services.odata.org/website/odata.svc/Customers(1)/Orders

Update an existing entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)

Update an existing linked entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)/Orders(1)

Merge an existing entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)

Merge an existing linked entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)/Orders(1)

Remove an existing entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)

Remove (i.e. set to null) a primitive property value in an existing entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)/FirstName/$value

Remove an existing linked entity
requestUri : http://services.odata.org/website/odata.svc/Customers(1)/Orders(1)

 

The method property in the request object determines, via an HTTP verb, the CRUD operation to perform. The following table shows the operations supported by the protocol and how they map to HTTP verbs.

Operation HTTP Verb
Add a new entity POST
Update an existing entity PUT
Delete an entity DELETE

The data property defines the payload of the request defined in the intermediate format. The request is passed as input to the handler object which serializes the request payload to the appropriate wire format; as controlled by the request headers. The transformed data is then stored in the body property. Finally, the modified request object is passed to the underlying network stack.

Some update operations, such as add, OData endpoint generate a response with the new item. This data is valuable because it provides useful metadata like the edit URI or concurrency information. It is also useful for any server generated property values. The response is processed by the appropriate handler. All responses trigger the invocation of either a success or error callback depending on the status of the HTTP response.

The success parameter of the request operation takes a callback function, which is executed if the request succeeds. If it is not defined then the default success handler is used from OData.defaultSuccess. It is a good practice to define your own success callback function.

The request function also takes an error parameter which is a callback function. The error callback function is executed if the request fails. If error callback function is not defined then the default error handler is used from the OData.defaultError.

Optionally a handler can be passed to the OData.request function. If it's not defined, the MIME-based handler is used, which looks at the Content-Type header and uses the correct handler to parse the payload results. For example if the data type is JSON then JSON handler would be invoked to parse the data.

The request function also takes in an httpClient object. If it is not defined then the default httpClient object is used from OData.defaultHttpClient.

Batch Operations
datajs request API also supports OData batch operations that that allow grouping multiple operations into a single HTTP request. Following two examples show how to do batch operations for GET, PUT and POST by using __batchRequests and __changeRequests
Example 1:

OData.request( {
requestUri: "http://ODataServer/FavoriteMovies.svc/$batch",
method: "POST",
data: { __batchRequests: [
{ requestUri: "BestMovies(0)", method: "GET" },
{ requestUri: "BestMovies(1)", method: "GET" }
]}
},
function (data, response) {
//success handler
}, undefined, OData.batchHandler);


Example 2:

OData.request( {
    requestUri: "http://ODataServer/FavoriteMovies.svc/$batch",
    method: "POST",
    data: { __batchRequests: [
            { __changeRequests: [
                { requestUri: "BestMovies(0)", method: "PUT", data: {MovieTitle: 'Up'} },
                { requestUri: "BestMovies", method: "POST", data: {ID: 2, MovieTitle: 'Samurai'} }
                ]
            }           
    ]}
},
function (data, response) {
    //success handler
}, undefined, OData.batchHandler);

 

Top

 

OData.defaultSuccess

Description: default callback function for APIs that succeed.

Odata.defaultSuccess = function (data, response)


Details

The OData.defaultSuccess property is used to fill in the value for calls that do not specify a success callback handler.

By default, it simply displays the string representation of data in an alert box. This is convenient for quick prototyping, for example you can type javascript:(function(){OData.read("/myservice.svc/Customers");})() in the location bar of the browser when datajs.js is available, and see the results in an alert box.

This property is not often used; instead, most API calls should include a situation-specific success handler.

Top

OData.defaultError

Description: default callback function for APIs that fail.

Odata.defaultError = function (error)

Details

The OData.defaultError property is used to fill in the value for calls that do not specify an error callback handler.

By default, it simply throws the given error, which may go unhandled and break into the debugger if one is running in the browser. This is convenient for debugging, but typically the library consumer can do something more appropriate.

This property is often used as a generic error handler hook when all or most API calls end up routing through the same error handling mechanism.

Note that the error object may contain more or less information depending on when the error was found. For example, failures that occur when a request is being sent will not have a response property, but failures that occur while processing the response typically will have this property set.

Top

OData.defaultHttpClient

Description: provides the default HTTP layer for datajs.

Odata.defaultClient = { request: function (request, success, error) } 

Details

The OData.defaultHttpClient property is used to fill in the value for calls that do not specify an HTTP client value.

The single property request provides a function that can be invoked with a request object, a success callback and an error callback.

By default, the library provides an HTTP client that relies on the XMLHttpRequest object to handle network requests.

The built-in HTTP client also provides properties to control the use of JSONP - see Cross-domain requests for additional information.

This property is typically left in its default state, although it may be replaced for advanced scenarios such as to add custom HTTP-level logging.

 Top

OData

The current OData support in datajs provides the ability to read and write to an OData service, using both the JSON and ATOM-based formats, including support for batch operations. The API is very simple and the library consists of only a few concepts.

The basic approach is as this: you can use OData.read with a URL to get data from a service, and the library will make sure that the reply comes in a consistent format. To add, update, or delete data, you can use OData.request with a request that includes the POST, PUT or DELETE methods and an object in that same format, and the library will take care of serializing it into the correct format.

For common cases, that's it. There are additional facilities to do more interesting things if you're interested, like tweaking the way the formatters work or the way that the OData.defaultHttpClient object uses the network.

Over time, we expect to build additional functionality that makes it easier to use so you don't have to deal with the payload format, or help with tracking changes, or making sure that you have a single instance if you ask multiple times for the same piece of data.

 Top

OData Snippets

The following snippet shows how to read a list of category names from the Northwind service, using jQuery to add them to an element with ID 'target-element-id'. Because the service supports JSONP, the default network library uses it even though the document comes from a different domain.

OData.read(
  "http://services.odata.org/Northwind/Northwind.svc/Categories",
  function (data) {
    var html = "";
    $.each(data, function(l) { html += "<div>" + l.CategoryName + "</div>"; });
    $(html).appendTo($("#target-element-id"));
  }
);

The following snippet shows how to add a new customer to an OData service that exposes a Customers resource set with Name, CustomerCategory and ID properties.

OData.request(
  { requestUrl: "/customer-service/Customers",
    method: "POST",
    data: { Name: "customer name", CustomerCategory: 123 } },
  function (insertedItem) {
    $("<div>inserted customer ID: " + insertedItem.ID + "</div>").appendTo($("#target-element-id"));
  }
);

TODO: add more samples, validate samples.

 Top

Metadata

Metadata is used by handlers to enhance how requests and results are processed. This corresponds to the Service Metadata Document as described in the OData documentation.

Metadata is optional for many scenarios, but it can be used to improve how server values are interpreted and annotated in their in-memory representations.

In some cases metadata makes it possible to understand models that cannot otherwise be processed correctly. For example, if a server maps an entity property outside of the entity content, the ATOM representation requires metadata to be able to extract the information from the right location in the document.

 Top

Security

The default HTTP library works by using the XMLHttpRequest object, which doesn't allow the page to get data from a server different from the one that served the page (this is often referred to as the same origin policy.).

This means that the library generally trusts the server to provide non-malicious payloads (the library is, after all, also provided by the same server).

This last point is why JSONP is disabled by default in the OData.defaultHttpClient object. If you trust the servers that you will be contacting, then you can turn support on by setting this property to true, as in the following snippet.

OData.defaultHttpClient.enableJsonpCallback = true;

To protect against man-in-the-middle attacks, you should enable and use the HTTPS protocol and refer to the data sources through 'https://' URLs.

 Top

Cross-Domain Requests

Browsers have a policy (commonly referred to as the same origin policy. that blocks requests across domain boundaries. Because of this restriction update operations cannot be performed if the web page is served by a domain and the target OData endpoint is in a different one. Users have the ability to disable this policy in the browser, however it is typically turned on by default. datajs is designed with such an assumption. The following options are available to support this scenario:

  • Have the web server provide a relaying mechanism to redirect requests to the appropriate OData endpoint.
  • Use an XDomainRequest object. This option is not available in all browsers.
  • Use cross origin XMLHttpRequest object. This option is also not available in all browsers.
  • Prompt for consent on first use. This option is not available in all browsers and generally provides a poor user experience.

Read operations are available for cross-domain requests if the OData server supports JSONP. To configure the datajs to use JSONP, set the following properties on the OData.defaultHttpClient object.

  • formatQueryString: this is a query string option inserted in the URL.
  • callbackParameterName: this is the name of a query string option that will be assigned a function name to call back into.
  • enableJsonpCallback: see Security before setting this property to true.

By default, all values except for enableJsonpCallback are set to work with the popular JSONP extension for WCF Data Services-based servers, but can be modified to any appropriate value before a request is submitted.

 Top

OData Internals

  • HTTP Client. This component makes network requests. The built-in handler is available as OData.defaultHttpClient, but can be replaced by any object with the same operations. You can easily mock it when testing your app.
  • Format handlers. These components turn raw payloads in JSON or ATOM format and turn them into a consistent in-memory representation.
  • Requests, responses and data. These are simply JavaScript objects that have certain specific members. There is no need to call constructors or anything of the sort; simply create a new object with the right shape and you're ready to go.
  • APIs. There are two APIs that can be used to read and write data, OData.read and OData.request. They simply glue all of the above with callbacks and provide a very simple way to interact with a data service.
  Comments ()
Recent Posts استفاده از تکنیکهای داده کاوی در سیستمهای لجستیکی روشهای کشف دانش از سیستمهای عملیاتی سازمانها ، استفاده از تکنیکهای داده کاوی آشنایی با استانداردهای مدیریت اطلاعات Cobit،ITIL،CMMI... IT service management Chaos theory تئوری هرج و مرج ۱۸ راه آزاد برای ذخیره هر نوع ویدئویی از اینترنت خلاصی از شر سایت های تبلیغاتی با کمک آقای گوگل و یک کلیک ساده گروه Qtel سرویس جدید سلامت و بهداشت موبایل معرفی می کند دیوار آتش و نحوه عملکرد آن Google crisis response
My Tags hanif sheikhabdolakrim (۱٢) فن آوری اطلاعات (٤) iran (٢) موبایل (٢) google (٢) داده کاوی (٢) itil (٢) managment and ict (٢) خدمات دولت الکترونیک (٢) ایران فن آوری اطلاعات (٢) it service management (٢) information technology (٢) codeplex (٢) net (۱) cobit (۱) سازمان های هوشمند (۱) logistic (۱) chilee (۱) دیواره آتش (۱) ذخیره هر نوع ویدئویی از اینترنت (۱) حنیف شیخ عبدالکریم (۱) india-chaos theory (۱) enterprise application (۱) پروژه های متن باز (۱) ajax control toolkit (۱) json (۱) web application (۱) datajs (۱) business processes (۱) programming (۱) firewall (۱) data mining (۱) net framework (۱) knowledge management (۱) هوش تجاری (۱) aspnet (۱) اپراتور سوم (۱) گوگل (۱) مایکروسافت (۱) اتاق بازرگانی (۱) دولت (۱) تحریم (۱) مدیریت دانش (۱) microsoft (۱)
My Friends نرم افزارهای Enterprise مایکروسافت asp.net http://www.codeproject.com/ باشگاه مدیران و متخصصان My Pardis