Use OData with MongoDB
On this page
Overview
OData (Open Data Protocol) is a standardized protocol for building and consuming RESTful APIs that allows for the querying and manipulation of data by using HTTP requests. It provides a uniform way to expose and interact with data from multiple sources.
In this tutorial, you will learn how to integrate OData with your MongoDB application.
Sample Data
This tutorial uses the sample_restaurants.restaurants
collection
from the Atlas sample datasets. To learn how to create a
free MongoDB Atlas cluster and load the sample datasets, see the Quick Start.
Tutorial
Install Dependencies
Create a new ASP.Net application named
ODataExample
and install the .NET/C# Driver. You can install the
driver by using the NuGet package manager in your IDE, or by running the
following command in the .NET CLI:
dotnet add package MongoDB.Driver
Then, install the MongoDB.AspNetCore.OData
NuGet
package through the NuGet Package Manager or through the .NET CLI by running the
following command:
dotnet add package MongoDB.AspNetCore.OData
Define your Models
Create a new folder in your solution called Models
and copy the
following Restaurant.cs
, Address.cs
, and GradeEntry.cs
files into the
folder:
public class Restaurant { [ ] public string Id { get; set; } public string Name { get; set; } [ ] public string RestaurantId { get; set; } public string Cuisine { get; set; } public Address Address { get; set; } public string Borough { get; set; } public List<GradeEntry> Grades { get; set; } }
public class Address { public string Building { get; set; } [ ] public double[] Coordinates { get; set; } public string Street { get; set; } [ ] public string ZipCode { get; set; } }
public class GradeEntry { public DateTime Date { get; set; } public string Grade { get; set; } public float? Score { get; set; } }
Note
The documents in the restaurants
collection use the snake-case naming
convention. The examples in this guide use a ConventionPack
to deserialize the fields in the collection into Pascal case and map them to
the properties in the Restaurant
class.
To learn more about custom serialization, see Custom Serialization.
Create an OData Controller
Create a new folder in your solution called Controllers
and add a new
controller file called RestaurantsController.cs
. Copy the following code
into the file:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.OData.Routing.Controllers; using MongoDB.AspNetCore.OData; using MongoDB.Driver; using ODataTest.Models; namespace ODataTest.Controllers; public class RestaurantsController : ODataController { private readonly IQueryable<Restaurant> _restaurants; public RestaurantsController(IMongoClient client) { var database = client.GetDatabase("sample_restaurants"); _restaurants = database.GetCollection<Restaurant>("restaurants") .AsQueryable(); } // Registers Get endpoint and sets max documents to 5 [ ] public ActionResult<IEnumerable<Restaurant>> Get() { return Ok(_restaurants); } }
This code performs the following actions:
Creates a constructor that connects to MongoDB, and gets the
restaurants
collection.Creates a
Get
endpoint that returns all restaurants in the collection.Specifies the
MongoEnableQuery
attribute to enable querying on theGet
endpoint.Specifies the
PageSize
attribute onMongoEnableQuery
to limit the number of documents returned to5
.
Configure the OData Service
Paste the following code into your Program.cs
file to configure the OData
service and map your controller endpoints.
using Microsoft.AspNetCore.OData; using Microsoft.OData.ModelBuilder; using MongoDB.Bson.Serialization.Conventions; using MongoDB.Driver; using ODataTest.Models; var builder = WebApplication.CreateBuilder(args); // Registers a convention pack to convert fields to camel case var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register( "CamelCase", camelCaseConvention, type => true); builder.Services.AddSingleton<IMongoClient>( new MongoClient("<Your connection URI>")); // Registers the Restaurants entity and sets the Id field as the key var modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet<Restaurant>("Restaurants"); modelBuilder.EntityType<Restaurant>().HasKey(r => r.Id); // Adds OData and specify query capabilities builder.Services.AddControllers().AddOData( options => options.Select() .AddRouteComponents("odata", modelBuilder.GetEdmModel()) ); var app = builder.Build(); app.UseRouting(); app.MapControllers(); app.Run();
Note
Replace the <"Your connection URI">
placeholder with your MongoDB connection string.
This code performs the following actions:
Instantiates a new
MongoClient
and registers it as a singleton in the dependency injection container.Defines the Entity Data Model (EDM) and registers
Restaurants
as an entity set with the keyId
.Adds the OData service and enables the
Select()
query operation.Registers the route by using the
AddRouteComponents()
method.Calls the
UseRouting()
andMapControllers()
methods to match incoming HTTP requests and route them to the appropriate endpoint.
Note
The .NET/C# Driver does not support OData-Aggregation with the
$apply
query operation.
Run the Application
Run the application by using your IDE, or by running the following command in your shell at the root directory of your project:
dotnet run ODataExample.csproj
After running the application, your terminal displays output similar to the following:
info: Microsoft.Hosting.Lifetime[14] Now listening on: http://localhost:5183 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: <Path to your project>
Tip
After running your application, your IDE might automatically open a
browser window to the URL where the application is running, which
displays a "page can't be found"
error. This is expected because the
application only has a single Get
endpoint configured.
Query the Data
To query the data, navigate to the Get
endpoint specified in the
application. To do so, open a browser and navigate to the localhost
URL specified in the terminal output from the preceding step. Then, append
the route for the Get
endpoint: /odata/Restaurants
. For example, if an
application is running at localhost:5183
, navigate to
http://localhost:5183/odata/Restaurants
.
If successful, the browser displays 5 restaurants in the collection, in JSON format. The output is similar to the following:
{ "@odata.context": "http://localhost:5183/odata/$metadata#Restaurants", "value": [ { "Name": "Glorious Food", "RestaurantId": "40361521", "Cuisine": "American", "Borough": "Manhattan", "Id": "...", "Address": { "Building": "522", "Coordinates": [-73.95171, 40.767461], "Street": "East 74 Street", "ZipCode": "10021" }, "Grades": [ ... ] }, ... ] }
Additional Information
To learn more about ASP.NET Core OData, see the Microsoft OData documentation.
To learn more about OData, see the OData documentation.