Featured image of post OData in a Nutshell

OData in a Nutshell

OData in a Nutshell

OData in a Nutshell

A Brief (and Somewhat Amusing) History

Once upon a time, in the golden age of APIs (okay, around 2007), Microsoft looked at the web and said, “You know what this world needs? More data!” But not just any data—data that could be queried like a database, yet accessed like a RESTful API. Thus, OData (Open Data Protocol) was born.

OData wasn’t just another API protocol; it was like a supercharged version of REST, with built-in support for querying, filtering, and manipulating data using familiar database-style syntax. It was like SQL for the web, minus the pain of writing actual SQL.

Over time, OData gained traction in enterprise environments where massive data sets roamed free, and developers desperately needed a way to manage them efficiently. Microsoft embraced it, added support in ASP.NET, and now it’s an industry standard maintained by OASIS (the organization, not the band 🎸).

Why Should You Care About OData?

  • It speaks SQL-ish – Instead of writing custom endpoints for every little thing, you can just add a few query parameters and get what you need. No more reinventing the wheel!
  • It’s standardized – Unlike every other homebrew JSON API, OData has well-defined rules and works consistently across platforms.
  • It’s super flexible – Need to sort, filter, or paginate? OData has your back. Want to expand related entities in a single request? No problem!
  • It plays well with Entity Framework – If you’re using EF, OData makes it ridiculously easy to expose your database via an API.

How to Use OData in ASP.NET Core

Let’s get down to business. Here’s how you can add OData to an ASP.NET Core Web API project.

Step 1: Install the Required NuGet Package

1
Install-Package Microsoft.AspNetCore.OData

Step 2: Configure OData in Program.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using Microsoft.AspNetCore.OData;
using Microsoft.OData.ModelBuilder;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Define the OData entity data model
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Products");

builder.Services.AddControllers().AddOData(opt => opt
    .Select()
    .Filter()
    .OrderBy()
    .Expand()
    .Count()
    .SetMaxTop(100)
    .AddRouteComponents("odata", modelBuilder.GetEdmModel()));

var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
app.Run();

Step 3: Create an OData-Enabled Controller

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using System.Collections.Generic;
using System.Linq;

[Route("odata/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
    private static readonly List<Product> Products = new()
    {
        new Product { Id = 1, Name = "Laptop", Price = 1200 },
        new Product { Id = 2, Name = "Smartphone", Price = 800 },
        new Product { Id = 3, Name = "Tablet", Price = 500 }
    };

    [HttpGet]
    [EnableQuery]
    public ActionResult<IQueryable<Product>> Get()
    {
        return Ok(Products.AsQueryable());
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

Step 4: Query the API Like a Pro

Once your API is up and running, you can do all sorts of cool things with OData queries:

  • Get all products: GET /odata/Products
  • Filter by price: GET /odata/Products?$filter=Price gt 800
  • Sort by name: GET /odata/Products?$orderby=Name asc
  • Select specific fields: GET /odata/Products?$select=Name,Price
  • Paginate results: GET /odata/Products?$top=2&$skip=1

No need to manually create extra endpoints. OData lets you query like a boss! 💪

OData vs. Regular REST API: The Showdown

FeatureODataRegular REST
Filtering$filterCustom query params
Sorting$orderbyCustom logic
Pagination$top, $skipLimit/Offset
Expanding Data$expandSeparate API calls
StandardizationYesNope, it’s the Wild West

The Downsides (Because Nothing is Perfect)

  • Overhead – OData adds some complexity that may not be necessary for small APIs.
  • Learning Curve – If you’re new to it, the syntax can feel weird at first.
  • Not Always Ideal for Public APIs – It’s great for internal data-heavy applications but can be overkill for simple APIs.

Key Ideas

ConceptSummary
ODataA standardized protocol for querying and manipulating APIs
HistoryCreated by Microsoft in 2007, now maintained by OASIS
BenefitsQuery flexibility, built-in filtering, sorting, and pagination
SetupSimple to integrate with ASP.NET Core and Entity Framework
DownsidesSome complexity, not always needed for small APIs

References