Use OData with MongoDB
For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt
Use OData with MongoDB
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 [Get Started with the .NET/C# Driver.](https://www.mongodb.com/docs/drivers/csharp/current/get-started.md#std-label-csharp-get-started
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:
shell
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:
shell
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:
```csharp public class Restaurant { [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; }
public string Name { get; set; }
[BsonElement("restaurant_id")]
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; }
} ```
```csharp public class Address { public string Building { get; set; }
[BsonElement("coord")]
public double[] Coordinates { get; set; }
public string Street { get; set; }
[BsonElement("zipcode")]
public string ZipCode { get; set; }
} ```
```csharp 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.](https://www.mongodb.com/docs/drivers/csharp/current/serialization/poco.md#std-label-csharp-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:
```csharp 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
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
[MongoEnableQuery(PageSize = 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
restaurantscollection. -
Creates a
Getendpoint that returns all restaurants in the collection. -
Specifies the
MongoEnableQueryattribute to enable querying on theGetendpoint. -
Specifies the
PageSizeattribute onMongoEnableQueryto 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.
```csharp 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
// Registers the Restaurants entity and sets the Id field as the key
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet
// 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
MongoClientand registers it as a singleton in the dependency injection container. -
Defines the Entity Data Model (EDM) and registers
Restaurantsas 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:
shell
dotnet run ODataExample.csproj
After running the application, your terminal displays output similar to the following:
none
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:
```json { "@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.
