4 out of 4 rated this helpful - Rate this topic

Guidance for OData in Windows Azure

Author: Glenn Gailey

Reviewer: Abhiram Chivukula

This article summarizes the current use of OData in the Windows Azure platform. It also provides guidance for creating, deploying, and consuming OData services hosted in Windows Azure.

This topic includes the following guidance sections:

This article assumes that you are familiar with WCF Data Services and ADO.NET Entity Framework. For more information about these .NET Framework technologies, see WCF Data Services and ADO.NET Entity Framework.

Overview: OData in the Cloud

The Open Data Protocol (OData) is a protocol that is based on representational state transfer (REST). When you create cloud-based data services, your data can be consumed by any client that supports HTTP messaging and that can process XML or JSON. OData exposes data as resources that are addressable by URIs. Data is accessed and changed by using standard HTTP verbs of GET, PUT, POST, and DELETE. OData uses the entity-relationship conventions of the Entity Data Model to expose resources as sets of entities that are related by associations.

Because it is based on internet standards, OData is a natural choice for creating REST-based data services in the cloud that are consumed by a wide range of internet-aware client platforms and devices. As such, OData is used by many features of the Windows Azure platform, including the following:

Windows Azure Storage Table Service
The programming interface used to access the Windows Azure Table service is OData. You can access the Table service by manually composing HTTP requests. For more information, see Table Service REST API. You can also use an OData client, such as the Windows Azure Storage client or the WCF Data Services client, to access the Table service. For more information, see Using the .NET Client Library with the Table Service.

Windows Azure Marketplace
The Windows Azure Marketplace is a subscription-based information and application market place that simplifies publishing and consuming data from various sources. Marketplace publishes data as OData feeds so that it can be easily consumed in your OData-aware applications. For more information, see Windows Azure Marketplace.

ACS Management Service
The Windows Azure Access Control Service (ACS) 2.0 provides an OData-based API for the ACS Management Service. For more information, see ACS Management Service API Reference.

You can also create and deploy your own OData service on Windows Azure. In this case, the data service is a .NET Framework-based Web application that is hosted by an ASP.NET Web Role. The following are features and toolkits that enable you to create and deploy OData services on Windows Azure:

WCF Data Services
WCF Data Services is a component of the .NET Framework that is used to create data service applications that implement OData. For more information, see WCF Data Services. WCF Data Services enables you to create customized Windows Azure-based data services that are hosted as ASP.NET Web Roles. Using WCF Data Services, you can expose data that originates from various Windows Azure sources, including SQL Database and Windows Azure Blob storage. The data services provider that you use to define the data model of the data service depends on the data source. For more information, see Data Services Providers (WCF Data Services).

Windows Azure Tools for Visual Studio includes an integrated set of tools for developing Windows Azure-based data services in Visual Studio. For an example of how to use Visual Studio tools to create and deploy a data service to expose OData feeds from a SQL database, see the article Data Services in the Cloud. For general guidance on creating and deploying OData services by using WCF Data Services, see Defining WCF Data Services.

Sync Framework Toolkit
The Sync Framework Toolkit extends the Microsoft Sync Framework to enable you to create a WCF Data Services-based sync service that can be deployed on Windows Azure. This specialized OData service enables you to synchronize data between a SQL database and various client applications and devices that can consume OData feeds. For more information, see the Microsoft Sync Framework Toolkit project page in MSDN Code Gallery.

For more general information about the OData protocol, including a list of OData producers and consumers and client libraries that support OData, see the OData.org web site.

Guidance for Using an Entity Framework Provider to Connect to SQL Database

You can use the Entity Framework provider in WCF Data Services to create a data service that publishes SQL Database data as OData feeds. For an example, see How to: Connect to Windows Azure SQL Database Through WCF Data Services. When you use the Entity Framework provider to define the data model for your data service, WCF Data Services uses the provided class, which inherits from ObjectContext, to compose and execute queries against the database. For more information, see Entity Framework Provider (WCF Data Services).

The following guidelines apply when using the Entity Framework provider to enable WCF Data Services to publish data from a SQL database.

Using an Entity Framework Code First Provider

The ADO.NET Entity Framework enables you to define a data model by using a designer (Model First), by mapping to an existing database (Database First), and by using your own Common Language Runtime (CLR) objects (Code First). For more information, see Creating and Mapping a Conceptual Model (Entity Framework). Code First was introduced in Entity Framework 4.1. Like the Model First approach, Code First enables you to define a data model without an existing SQL database. Code First automatically generates a new SQL database in the targeted SQL Database server. The tutorial Developing a Windows Azure Data Application Using Code First and Windows Azure SQL Database shows you how to create a Code First data model for a SQL database.

When you use Code First to define your data model, you define a context class that inherits from DbContext instead of ObjectContext. However, when using the Entity Framework provider with WCF Data Services, the DataService class must be of a type that inherits from ObjectContext. There is a workaround that enables you to use a Code First data model with WCF Data Services. You must override the CreateDataSource to explicitly supply the underlying ObjectContext to the data services runtime. For an example of how to do this, see the article Using Entity Framework 4.1 Code First with WCF Data Services.

Mitigating SQL Database Connection Faults

When you use the Entity Framework to access data in a SQL database, we recommend that you attempt to mitigate connection faults. As described by the article Windows Azure SQL Database and Entity Framework Connection Fault Handling, there are several ways in which you can mitigate SQL Database connection faults to when using Entity Framework. There is currently no automatic retry mechanism in either Entity Framework or WCF Data Services. When using the Entity Framework provider, WCF Data Services manages the ObjectContext for you. This means that there is no way to inject retry logic into individual Entity Framework operations. Because of this, you instead must implement retry logic to clear the connection pool of any invalid connections that could cause failure during execution.

When You Have a Model First or Database First Model

When you use the Entity Framework tools to create a Model First or Database First data model, the tools generate a strongly-typed ObjectContext as a partial class. This partial class includes a partial OnContextCreated method.

To mitigate connection faults, implement the following method in a separate code page in your data service project:

partial void OnContextCreated()
{
    int MaxRetries = 10; 
    int DelayMS = 100; 
    RetryPolicy policy = 
        new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(
            MaxRetries, TimeSpan.FromMilliseconds(DelayMS)); 

    // Invoke the query in an inline delegate using the lambda operator.
    policy.ExecuteAction(() =>
    {
        try
        {
            // Try to open the connection.
            Connection.Open();
            var storeConnection = 
            (SqlConnection)((EntityConnection)Connection)
            .StoreConnection;

            // Send a quick query to the SQL database to test the connection.
            new SqlCommand("declare @i int", storeConnection).ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            // If we fail, close the connection.
            Connection.Close(); 
            throw ex;
         }
      });
}

This method introduces retry logic when the context is created to send inexpensive queries to SQL Database to clear the connection pool. The retry logic is provided by the RetryPolicy class in the Transient Fault Handling Application Block, which is included with the Enterprise Library 5.0 Integration Pack for Windows Azure—November 2011. This application block is also available as a Nuget package. The previous code sample requires the following using statements:

using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.SqlAzure;
using Microsoft.Practices.TransientFaultHandling;
using System.Data.EntityClient;
using System.Data.SqlClient;

When You Have a Code First Model

When you use Code First to define an Entity Framework data model, you must override the CreateDataSource to explicitly supply the underlying ObjectContext to the data services runtime. For more information, see Using Entity Framework 4.1 Code First with WCF Data Services. For a data service based on a Code First data model, you perform a similar retry operation in your method that overrides the CreateDataSource method. The following is the method override for a Code First data model based on Northwind:

// You must override CreateDataSource to manually return an ObjectContext,
// otherwise the runtime tries to use the built-in reflection provider instead of 
// the Entity Framework provider.
protected override ObjectContext CreateDataSource()
{
    // Create a new Code First Northwind DbContext.
    NorthwindContext nw = new NorthwindContext();
    nw.Configuration.ProxyCreationEnabled = false;
    
    // Define a retry policy for our query to the SQL database.
    int MaxRetries = 10;
    int DelayMS = 100;
    RetryPolicy policy =
        new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(
            MaxRetries, TimeSpan.FromMilliseconds(DelayMS));

    
    // Invoke the query in an inline delegate using the lambda operator.
    policy.ExecuteAction(() =>
    {
        try
        {
            // Try to open the connection.
            nw.Database.Connection.Open();
            var storeConnection = (SqlConnection)(nw.Database.Connection);

            // Send a quick query to the SQL database to test the connection.
            new SqlCommand("declare @i int", storeConnection).ExecuteNonQuery(); 
        }
        catch (Exception ex)
        {
            // If we fail, close the connection.
            nw.Database.Connection.Close();
            throw ex;
         }
    });

    // Configure DbContext before we provide it to the 
    // data services runtime.
    nw.Configuration.ValidateOnSaveEnabled = false;

    // Get the underlying ObjectContext for the DbContext.
    var context = ((IObjectContextAdapter)nw).ObjectContext;

    // Return the underlying context.
    return context;
}

As with the previous example, this code uses the RetryPolicy class in the Transient Fault Handling Application Block.

Leveraging Blob Storage

An OData service can expose binary large object (BLOB) data. The Open Data Protocol (OData) defines a mechanism for retrieving binary data independent of the entity to which it belongs. This is accomplished by separating the binary data from the entity in a separate data stream. With WCF Data Services, you define a binary resource stream by implementing the IDataServiceStreamProvider interface to define a streaming data provider. The streaming provider implementation supplies the data service with the stream associated with a specific entity as a Stream object or as a URI that is used to access the binary data. For more information, see Streaming Provider (WCF Data Services).

When creating a streaming data service provider for a data service hosted in Windows Azure, use the Windows Azure Blob service when implementing GetWriteStream and GetReadStream. For the best performance, your GetReadStreamUri implementation should return the URI of the Blob so that clients can request it directly from the Blob service.

Securing an OData Service

There are scenarios where it makes sense to publish a Windows Azure-based OData service that allows anonymous access. However, in many cases you must determine who is accessing the data service. In security terms, this “who” is known as the principle. You must also determine whether a given principle can access resources, and (potentially) filter the results of queries based on the principle making the request. You may also need to secure the data returned by the data service to prevent disclosure to a third party. For general information about securing WCF Data Services, see Securing WCF Data Services.

Authentication
WCF Data Services does not perform authentication of client requests. Instead, it relies on the hosting platform to perform authentication and to provide it with information about the requesting principle. When you implement authentication for a data service hosted in Windows Azure, you should use OAuth 2.0 authentication. In the Windows Azure platform, support for this authentication scheme is provided by the Access Control Service (ACS). For an example of how to use the ACS to implement OAuth 2.0 authentication for your data service, see the article OData and OAuth—Protecting an OData Service Using OAuth 2.0.

For an example of how to connect to an OData service by using OAuth 2.0, see the article Connecting to an OAuth 2.0 protected OData Service.

Authorization
We recommend that you define rules that restrict access to data model resources to the minimum set of privileges required to support client applications. For more information, see Configuring the Data Service (WCF Data Services). Once a client has been authenticated, information, such as a user name, can be obtained from the identity of the principle. Depending on the data model, this client-specific information can be used to filter data before it is returned to the client by the data service. You can do this by defining query interceptors for specific entity sets that must be filtered. For more information, see Interceptors (WCF Data Services).

Defining query interceptors that return only data that belongs to a specific principle or role enables WCF Data Services to support multitenant applications. In the multitenant model, a single data service can service many clients while keeping their data separated. For more guidance on creating multitenant Windows Azure-based applications, see Designing Multitenant Applications on Windows Azure. You can also define change interceptors to inject business logic when a change is sent to the data service. This logic can also check the principle of the authenticated request and, potentially, roll-back changes made by a user that is not authorized to make the change.

Republishing the Table Service Not Recommended

The TableServiceContext class, which is used to access the Windows Azure Table service, is based on the WCF Data Services client. It is possible to republish Table service OData feeds by using the reflection provider with TableServiceContext. However, the WCF Data Services client library does not support the full set of language integrated query (LINQ) queries used by an OData service. Because of this, it is not recommended that you republish the Table service by using WCF Data Services.

Guidance for Enhancing WCF Data Services Applications

This section contains other guidance for WCF Data Services hosted in Windows Azure. This guidance can be used to provide an improved experience for clients that access an OData service.

Define Page Limits for Large Entity Sets
When you use WCF Data Services to expose large sets of data, you should set page limits to restrict the number of entities returned to clients in a single query. Without page limits, a few clients could easily consume excess resources by issuing simple requests against feeds that contain many entities. Page limits work to distribute large queries into a number of smaller partial queries, which reduces the impact of large queries on the overall response times of the system. To set page limits, call the SetEntitySetPageSize method on each entity set exposed by the data service. For more information, see How to: Enable Paging of Data Service Results (WCF Data Services).

Enable the $format System Query Option in WCF Data Services
WCF Data Services supports both Atom XML and JSON, as required by OData. When WCF Data Services receives a request, it checks the Accept request header to determine the format of the response. OData also provides a $format query option that can be used by clients that are not able to set the requests headers, such as some JavaScript clients and the browser. By default, WCF Data Services ignores this system query option. For more information, see WCF Data Services Protocol Implementation Details.

Enabling support for the $format query option also enables support for JavaScript Objection Notation with padding (JSONP) in client-side JavaScript webpage code when calling an OData service. You can add this functionality to your data service by downloading the JSONP and URL-controlled format support for WCF Data Services sample project from the MSDN Code Gallery Web site and adding it to your data service project.

Guidance for OData Clients

This section describes the level of client support for accessing OData services and guidance for clients that access an OData service.

Client Support for Accessing OData Services
Because OData is based on standard internet protocols, an OData service can be accessed by any client that can send and received HTTP messages and that can compose and parse XML or JSON. To reduce the amount of work required to access an OData service, there are various client libraries and client applications that can be used to consume OData services, including the following:

For a comprehensive list of OData client libraries, see the OData SDK. For a list of applications that consume OData feeds, see the Consumers page on the OData Web site.

Mobile Client Considerations
The following considerations apply when accessing OData feeds from a mobile device application:

  • Always enable client-side paging so that the client has control of how much data gets sent by the service. This is done by using the $skip and $top query options in the request URI.

  • Always be prepared to handle a paged response from the server. In WCF Data Services, the next page is requested by using the $skiptoken query option in a query URI. For more information, see How to: Load Paged Results (WCF Data Services).

  • If you only need a count of the number of items in the feed, request just the count value and not the entire feed. This count can be done by requesting the $count endpoint or by including $inlinecount=allpages in the request URI. For more information, see How to: Determine the Number of Entities Returned by a Query (WCF Data Services).

  • Consider using the JSON format instead of Atom XML to reduce network bandwidth.

    noteNote
    WCF Data Services clients, including the OData client for Windows Phone, do not currently support the JSON format.

  • Consider using compression to reduce network bandwidth. Compression requires additional processing by both the data service and the client device. This additional processing can have a negative impact on the battery life of the device.

  • Consider strategies, such as client projections that use the $select query option, to reduce the amount of data sent to the client. For more information, see Query Projections (WCF Data Services).

  • Cache reference data on the client, or implement some other synchronization strategy to reduce the amount of overlapping data downloaded from the data service. For more information, see Data Synchronization between Windows Azure and Mobile Clients.

For guidance that is specific to the Windows Phone platform, see Using Windows Phone with Windows Azure.


Build Date:

2013-04-18
Did you find this helpful?
(1500 characters remaining)

Community Additions

ADD
© 2013 Microsoft. All rights reserved.
facebook page visit twitter rss feed newsletter