Implementing OData in ASP.Net API

OData is a protocol that allows creating custom queries to simple REST services. Using OData query parameters you can filter, sort or transform output you’re getting to fit your needs without any implementation changes on the API side. It sounds groundbreaking and innovative and it actually is, but it’s not a new thing – Microsoft introduced it in 2007.

Is it a lot of work to introduce OData to existing API?

No! It is surprisingly easy. Let’s try it on a simple WebApi controller in a ASP.NET framework. First you need to install nuget package: Microsoft.Data.OData. Let’s say we have a such REST api controller:

public class FoldersController : ApiController
{
    private IFoldersAndFilesProvider _provider;

    public FoldersController(IFoldersAndFilesProvider provider)
    {
        _provider = provider;
    }

    [Route("api/Folders")]
    public IHttpActionResult GetFolders()
    {
        var folders = _provider.GetFolders();
        return Ok(folders);
    }
}

This is a very simple controller that returns a list of folders in a tree structure. All there is need to be done to make this endpoint OData friendly, we need to change endpoints attributes and return IQueryable result.

[Route("odata/Folders")]
[EnableQuery]
public IQueryable<Folder> GetFolders()
{
    var folders = _provider.GetFolders();
    return folders.AsQueryable();
}

And this is it! So…

Let’s see some magic

Plain old REST endpoint would return all folders, but with OData we can query that output.

http://localhost:51196/odata/Folders

Will return the same full result.

http://localhost:51196/odata/Folders?$orderby=Size

This query will sort the output by folders size.

http://localhost:51196/odata/Folders?$top=5

There is a way to return only few results.

http://localhost:51196/odata/Folders?$skip=10&$top=5

Or use for returning partial result or even paging.

http://localhost:51196/odata/Folders?$filter=Folders/all(folder: folder/Size ge 10000)

More complex query can get folders only above certain size.

http://localhost:51196/odata/Folders?$filter=Folders/all(f: f/Hidden eq false)

Or only those that are not hidden.

You can find more examples like this here.

Not only getting data

OData is perfect for querying data, but it also can be used for adding, updating, patching and deleting entities. In Visual Studio you can add a ODataController and it will prepare a controller for you with pre-generated CRUD operations that you can use.

odata-add-controller

There are good developer articles about OData here.

This post is just scratching the surface and Microsoft implementation offers a lot, but it offers only a subset of OData features. Works on this subject seems to stop a few years ago, but there’s a new hope on the horizon. Microsoft is working on OData support for .Net Core APIs. You can track progress in this gitub repository. And here you can find some guidelines how to start using this new package.

What can I use it for

OData offers query options for simple REST APIs, that would normally require a lot of developers work to handle all the cases. In my opinion OData is perfect for scenarios where you serve data for many clients that needs different data. It could be a perfect API for automatition tests, that can fetch data that they need at the moment, without hardcoding them. Also it can be a nice addon for APIs that you don’t intend to maintain actively.

All code posted here is also available in my github repo here.

Leave a Reply

Your email address will not be published. Required fields are marked *