New IQueryable Support for Http Services in WCF

One of the things that caught my attention when WCF Data Service was released a couple of years ago was the ability of using URI segments for passing queries directly to an underline linq provider. This represented a very powerful feature for allowing clients to filter and manipulate a large data result set on the server side with a simple API and without incurring in any unnecessary performance penalty (the queries are performed and resolved in the data source itself most of the times) and having all that logic implemented in the service itself.

I’ve always thought that this cool feature should be something that anyone could reuse in any service, and not something available in WCF data services only. For example, If you already had an existing REST service implementation, moving that logic to a WCF data service with OData support was only the option you had if you wanted to reuse that query support.  By moving your service to a WCF Data Service, you were also limiting your service to the content types supported by OData (Xml Atom and JSON), and it would only makes sense with services centered around the concepts of CRUD for manipulating data.

Fortunately, this functionality has been moved to a separated library and released as part of the new WCF Web APIs in wcf.codeplex.com. This means that you can now use the IQueryable support with almost the same linq operators that you already have in WCF Data Service as part of any existing WCF Http Service.

There is a new “QueryComposition” behavior that you can associate to one of the service operations to support querying over the response data.

private static List<Contact> contacts = new List<Contact>()
{
    new Contact { Name = "First Contact", Id = totalContacts++ },
    new Contact { Name = "Second Contact", Id = totalContacts++ },
    new Contact { Name = "Third Contact", Id = totalContacts++ },
    new Contact { Name = "Fourth Contact", Id = totalContacts++ },
};
 
[WebGet(UriTemplate = "")]
[QueryComposition]
public IEnumerable<Contact> Get()
{
    return contacts.AsQueryable();
}

In the example above, the service operation “Get” is returning a list of contacts in which some of the Linq query operators can be passed as part of the request URL as the “QueryComposition” attribute has been associated to the operation.

Therefore, you can do some of the following things,

Use the "#filter” segment to filter some of the data in the response resulset - http://localhost:8081/contacts/?$filter=Name eq 'First Contact'

Use the “#top” or “#skip” to get a subset of entries in the response - http://localhost:8081/contacts/?$skip=2&$top=1

And of course, many of the other supported operators available today as part of the OData spec can also be used.

In addition to what you can do on the server side, there is also a nice support on the client side with a new IQueryable implementation that knows how to pass many of the linq operators as part of the URL to the service. This new implementation is “WebQuery<T>” and it is part now of the HttpClient library also available as part of this WCF drop in codeplex.

string address = "http://localhost:8081/contacts/";
HttpClient client = new HttpClient(address);
IQueryable<Contact> contacts = client.CreateQuery<Contact>().Where(c => c.Name == "First Contact");

In the example above, the client library will submit the following request to the service, http://localhost:8081/contacts/?$filter=Name eq 'First Contact'. Several extensions methods have been added for the HttpClient class for creating new instances of WebQuery<T>.

This is only one of the cool features that the WCF team has added to the Http Stack, so I will explore the rest more in detail in following posts.

Published Monday, November 1, 2010 1:16 PM by cibrax
Filed under: , ,

Comments

No Comments