ApiController vs ODataController when exposing DTOs
Asked Answered
S

1

24

Can someone explain me when I should inherit my controller form ODataController vs ApiController ?

The question is caused by the fact that results returned by ApiController can be filtered with OData query.

If I apply QueryableAttribute to controller's methods, query is processed even if action returns IEnumerable.

However without this attribute but with the call config.EnableQuerySupport(), query is processed only if method returns IQueryable.

I think it is not consistent behavior. WebAPI documentation and examples imply that controller must inherit from ODataController. And I'm a little confused.

Either ApiController accidentally and partially supports part (at least $skip, $filter and $top) of OData protocol. Or this is by design and I need ODataController for complete ODataSupport.

The real problems is that my service exposes DTOs, not POCOs. There may be no one to one mappings. There's need to convert OData query against DTOs to EF query against POCOs.

Now just playing with OData. I retrieve entities and convert them to DTOs. Admittedly, this is not very performant to get all of them from DB for each request yet tolerable for experiments. But there's definitely no need to return all entities to the client if it requires some filtered subset of DTOs.

OData query started working out of the box with ApiController and Querayble attribute, but the aforementioned inconsistency makes me thing I doing something wrong.

Spindell answered 14/8, 2013 at 13:27 Comment(1)
I think it's because it implements additional functionality like metadata allowing WCF Data Services client to be used: sravi-kiran.blogspot.co.nz/2013/08/…, blogs.msdn.com/b/webdev/archive/2013/01/29/…, asp.net/web-api/overview/odata-support-in-aspnet-web-api . Web API (with query support) came out Jan 2012 and Web API OData in Jan 2013 so I think you're right with "I need ODataController for complete ODataSupport" to match OData spec.Bathe
S
14

Can someone explain me when I should inherit my controller form ODataController vs ApiController?

You would want to inherit from ODataController if you want to expose an endpoint that adheres to the OData protocol. If you want to do something else, such as a REST endpoint, then inherit from ApiController.

Applying some parts of the WebAPI OData framework but not others is probably not a good idea. It may in some cases, but will probably not work well in others. For example you may get querying support, but the $metadata endpoint may not be generated (that's just speculation, the actual symptoms may be different).

It sounds like you're using EntityFramework already. I know there are a number of samples showing how to expose that as an OData endpoint.

If you don't want to do that for some reason, you can implement querying yourself. This is briefly covered in a few places on this tutorial, but the gist is to add a parameter of type ODataQueryOptions<T> to your action, and use the methods on it to filter your result set. However, it can be painful to generate good database queries for all possible OData queries, so you should avoid that if possible.

Spongin answered 14/8, 2013 at 17:20 Comment(3)
Thanks. I changed the wording of my question. Hope it became more clear.Spindell
I think it may be a good idea if you separate your controllers in their own directory. Like make an API folder and an OData folder in your Controllers folder. One advantage of using OData is that you don't have to create a new hardcoded linq query for each requested item; it's very useful for querying a single entity (not joined entities). The querying url auto generates the linq expression for you. By eliminating the need of adding new linq queries, you avoid code maintenance and overhead for your project.Coppins
I'd use APIController for complex joined entity relationships, and OData for simple single entity relationships.Coppins

© 2022 - 2024 — McMap. All rights reserved.