Click here to Skip to main content
16,019,983 members
Articles / Web Development / ASP.NET

Your App needs filtered data - Use ODATA

Rate me:
Please Sign up or sign in to vote.
4.41/5 (5 votes)
14 Sep 2015CPOL4 min read 25.4K   6   13
For those who are still doing old school REST, a pointer in the direction of ODATA

Introduction

It is more than a common scenario that our apps(be it mobile apps or web apps) are backed by a service. These services are often RESTful these days as the benefits and flexibility of REST in undeniable. But its more than often that I see these services that are being written for consumption from the apps tend to have the endpoints exposed as per client app requirements. We recently inherited some code for a project that is an ASP.NET Web API that is meant to be consumed by an angular app(phonegap based hybrid mobile app). To my surprise this Web API is exposing the endpoint that is tailored for angular app needs. Things like, page size, page number, search sort etc are being passed to the API's action method to get the filtered data on the app.

Background

I could be wrong but to me it felt like in some way approach like this is polluting the Web API based since the API endpoints are being dictated by client app requirements. What if we have another app that has some different kind of requirements for data. Will we be exposing more endpoints to cater to that. The most painful point is the implementation that exist for each endpoint. We have to have action methods on the API end to cater to these requirement. Ultimately the API get bloated catering to all these needs and becomes a maintenance nightmare.

There is nothing wrong in this approach but the point being if it is serving our purpose and we are able to live with the complexity. But for such services why not follow a rather standardized approach. If you are thinking ODATA then you are right on the money.

ODATA is a protocol using which we can share and access the data using AtomPubprotocol. This AtomPubprotocol is mainly used in creating feeds from websites. It is built on of the REST architecture philosophy where the CRUD operations in the remote data resource can be performed using HTTP protocols like GET, PUT, POST and DELETE.

For more information on ODATAhttp://www.odata.org/

ODATA and ASP.NET Web API

Now from the ASP.NET Web API perspective its rather very easy to support ODATA. The best part about having a Web API is that it is already built for creating restful services. And it is rather very easy to create the ODATA compliant Web API. If I have to put it in simple words - Creating an ODATA compliant Web API is just a matter of importing a nuget package. In fact visual studio comes with a scaffolding template that can be used to generate the ODATA compliant API controllers. All the magic of converting the APIControllors into ODATA compliant controllers is in the following nuget package: Microsoft.AspNet.Odata.

For a step by step tutorial on how to create ODATA compliant Web API: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint

The only thing to note here in case we use the visual studio scaffolding for ODATA API controller is that it will put the ObjectContext and data access code in the controller itself. Which is perhaps not a good idea from patterns perspective. So in case we want we want our controllers to use the Repository pattern, we just need to make sure that our repositories return IQueryable and not IEnumerable and the ODATA package will take care of the rest.

UPDATE: Someone asked a very interesting question about how the connection management will work with this. To clarify on this point, using ODATA does not mean that we are creating a live connection between client server. Its the parameters that are being passes in ODATA format and the controllers are evaluating the paramters in the traditional way they would have managed in a plain APIController. To understand this a but better lets look at a method created in the Controller.

C#
public class MoviesController : ODataController
    {
        private MoviesDbEntities db = new MoviesDbEntities();

        // GET: odata/Movies
        [EnableQuery]
        public IQueryable<Movie> GetMovies()
        {
            return db.Movies;
        }

}

In the above code, connection management is no different here than the traditional action methods. since the Context class object will get disposed as soon as the controller gets disposed. 

SO how does ODATA queries work magically? What happens here is that the attribute EnableQuery that is put on top of our query methods look at the ODATA specific parameters in the URL/querystring. It will then take the return values from our action method i.e. the IQueryable and apply LINQ on that depending on what IDATA parameters were passed by user(before returning it to the caller). After this LINQ is applied and the final data is ready to be returned, the dispose method of the respective context class and the controller will get called taking care of the connection disposal.

Note: The overall Philosophy here is to let the service expose the data in a standard format and apps consume the data using this format. No need to expose endpoints based in consuming apps requirements. I just provide references to be able to create ODATA compliant ASP.NET Web API but the same philosophy can be utilized by any technology stack.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India

I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.

  • Microsoft Certified Technology Specialist (MCTS): Web Applications Development with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Accessing Data with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Windows Communication Foundation Development with Microsoft .NET Framework 4

If you like my articles, please visit my website for more: www.rahulrajatsingh.com[^]

  • Microsoft MVP 2015

Comments and Discussions

 
QuestionIQueryable is a leaky abstraction to expose. Pin
Member 39559233-Dec-15 15:23
Member 39559233-Dec-15 15:23 
What is stopping the caller from selecting the top 50,000 records for a return set in your OData param'd query? What is stopping the caller from selecting sensitive rows that arent meant for them.

The barebones implementation of OData exposes EF objects over the wire for a free-for-all.

Having security,performance, grouping, data aggregation, etc... in consideration for your API then forget about it. Its LESS work to NOT have OData than it is TOO have OData.

By the time you limit your queries per user security, perform any joining across tables, .. at this point you're creating custom models to even return and receive from your client because noone ever wants just a single POCO in a single call. Youre basically doing MORE work implementing OData than it is to have a traditional REST Web API.

We've given OData a go several times at my workplace and the only thing it is ever good for is simple CRUD operations on segregated entities. Anything more then that and the "simple" of OData goes right out the window.
QuestionShould only be used in small data low usages sites Pin
Member 1041007617-Sep-15 7:57
Member 1041007617-Sep-15 7:57 
AnswerRe: Should only be used in small data low usages sites Pin
Rahul Rajat Singh17-Sep-15 15:21
professionalRahul Rajat Singh17-Sep-15 15:21 
GeneralRe: Should only be used in small data low usages sites Pin
Member 1041007618-Sep-15 5:23
Member 1041007618-Sep-15 5:23 
GeneralRe: Should only be used in small data low usages sites Pin
Rahul Rajat Singh18-Sep-15 6:42
professionalRahul Rajat Singh18-Sep-15 6:42 
Question"that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
ignatandrei16-Sep-15 1:36
professionalignatandrei16-Sep-15 1:36 
AnswerRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
Rahul Rajat Singh16-Sep-15 1:42
professionalRahul Rajat Singh16-Sep-15 1:42 
GeneralRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
ignatandrei16-Sep-15 2:48
professionalignatandrei16-Sep-15 2:48 
AnswerRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
Rahul Rajat Singh16-Sep-15 2:53
professionalRahul Rajat Singh16-Sep-15 2:53 
GeneralRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
ignatandrei16-Sep-15 3:01
professionalignatandrei16-Sep-15 3:01 
GeneralRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
Rahul Rajat Singh16-Sep-15 3:02
professionalRahul Rajat Singh16-Sep-15 3:02 
GeneralRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
ignatandrei7-Jan-16 22:24
professionalignatandrei7-Jan-16 22:24 
AnswerRe: "that our repositories return IQueryable and not IEnumerable and the ODATA package" Pin
Rahul Rajat Singh20-Jan-16 0:09
professionalRahul Rajat Singh20-Jan-16 0:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.