Using Linq2Rest as a Client

Tags: Linq2Rest, LINQ, REST, Web

In this tutorial I explained how to use Linq2Rest in an ASP.NET or ASP.NET MVC application. This time we will be looking at how to use Linq2Rest in a client application in order to generate a web request to retrieve the results of a LINQ query.

Before we go any further, I should warn you that the tutorial will not go into the details about types, interfaces, projections and LINQ queries. It is assumed that you understand how to write LINQ queries as well deserializing web responses.

The request generation and invocation is handled by the RestContext<T> class. The constructor takes two arguments: an IRestClient and an ISerializerFactory. The IRestClient interface is a wrapper around a web request invocator, i.e. a class which can download a result from a REST service. The project includes a public RestClient class which will request JSON data from the service endpoint that you define, but it is recommended that you write your own implementation. I am not going to go into the expectations when it comes to requesting a resource from a RESTful service. You will have to look know what service you wish to depend on.

The ISerializerFactory is a wrapper around a serializer which will be what converts the downloaded data back into an object (or more likely, a list of objects). It may seem a bit convoluted to require a serializer factory, why not just use a serializer? The reason is that the context can live longer than one request and each query can return a different object type, because Linq2Rest supports projections (i.e. Select queries), which means that the result is not known in advance. For this reason the serializer factory must be capable of providing a serializer for the expected response type.

It should be obvious, but I am going to say it anyway, there has to be a corelation between what your IRestClient downloads and what the serializer can handle. So don't provide an IRestClient that downloads JSON if you are going to provide XML serializers.

To set up your context, simply create an instance of the RestContext class, like so:

IRestClient restClient; // Create an instance of your concrete implementation.
ISerializerFactory serializerFactory; // Create an instance of your concrete implementation.
RestContext<yourresourcetype> provider = new RestContext<yourresourcetype>(restClient, serializerFactory);

Once you have created your context, you can start querying the Query property, like so:

var result = provider.Query
	.Where(x => x.Value <= 3)
	.Select(x=> new { x.Value, x.Content })
	.OrderBy(x=> x.Value)
	.Skip(1)
	.Take(1);

What happens when this query gets executed is, that Linq2Rest will generate a web request using the provided IRestClient and download the response from the web service. The response will be deserialized and returned as the requested type. This means that the full round trip of requesting a resource from a web service is encapsulated. As long as the end point supports OData style parameters, the response can be limited to what is required to satisfy the query, which will most likely result in a smaller download, since the filtering can be applied on the server.

In the example above the query includes a projection, which means that the resulting type is an anonymous type. The passed serializer factory must be able to deserialize into an anonymous type. The Linq2Rest.Mvc package includes a SimpleAnonymousTypeSerializer which you can use to generate anonymous types from a projected response. It is called simple because it handles built in CLR types, but provides to assurances that it can handle complex object graphs.

Linq2Rest is published under Microsoft Public License and can be found on BitBucket and Nuget (The Linq2Rest.Mvc project on Nuget).

Latest Tweets