Advanced Tutorial
The Open Data Protocol (OData) is a data access protocol built on core protocols like HTTP and commonly accepted methodologies like REST for the web. There are various kinds of libraries and tools that can be used to consume OData services. But for beginners and those who want to write their own libraries, the pure HTTP requests and responses are also very important. This documentation will not cover every feature details for OData V4 services but will try to cover various typical scenarios. If you want to have a more detailed understanding, please refer to OData Documentation.
Note:
- This is the advanced section. For topics like requesting data, query options, basic data modification, operations and etc, please refer to Basic Section.
- All these are based on OData V4 sample service TripPin, please just replace the
serviceRoot
below with the URLhttps://services.odata.org/V4/TripPinServiceRW
. TripPin now supports ETag, so for data modification topics, you should first using GET on TripPin (eg. GET serviceRoot/People) to get the section information in the payload then use the URL with section for data modification examples. (something looks like https://services.odata.org/V4/(S(flat4rgegiueineatspfdku1))/TripPinServiceRW) - You may use Fiddler to run the request (especially the complex ones of data modification) and get the JSON response.
- In TripPin service, ETag is currently enabled on entity Person. We omit the ETag related headers in request headers for short, please go to the ETag Section for detailed information.
- We will keep improving this by adding contents and fixing bugs. You can provide your feedbacks and ask questions using OData Mailling List.
Singleton
Singletons are single entities which are accessed as children of the entity container.
Requesting singleton
The request below returns the singleton Me
GET serviceRoot/Me
Response Payload
Requesting property of Singleton
The request below returns the property AddressInfo of singleton Me.
GET serviceRoot/Me/AddressInfo
Response Payload
Update Singleton
The request below updates the UserName of Single Me.
PATCH serviceRoot/Me
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type" : "Microsoft.OData.SampleService.Models.TripPin.Person",
"UserName": "AprilTripPin"
}
Response Payload
Derived Entity Type
OData now supports derived entity type. Entity types may derived by single inheritance from other entity types. In the sample TripPin service, the entity type Event and Flight both derive from entity type PlanItem.
Requesting a Derived Entity
The request below returns the flight of with PlanItemId 21.
GET serviceRoot/People('russellwhyte')/Trips(1003)/PlanItems(21)/Microsoft.OData.SampleService.Models.TripPin.Flight
Response Payload
Requesting a Derived Entity Collection
The request below shows how to get the derived enity set Flights.
GET serviceRoot/People('russellwhyte')/Trips(1001)/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight
Response Payload
Filter on Derived Type
The two request below shows how to filter on derived entities. These requests return all Flight deriving from PlanItem which has FlightNumber as 'VA1930'.
serviceRoot/People('russellwhyte')/Trips(1001)/PlanItems?$filter=Microsoft.OData.SampleService.Models.TripPin.Flight/FlightNumber eq 'VA1930'
serviceRoot/People('russellwhyte')/Trips(1001)/PlanItems/Microsoft.OData.SampleService.Models.TripPin.Flight?$filter=FlightNumber eq 'VA1930'
Response Payload
Create a Derived Entity
The request below creates an event entity in trips. Event derives from PlanItem.
POST serviceRoot/People("russellwhyte")/Trips(1003)/PlanItems
OData-Version: 4.0
Content-Type: application/json
;
odata.metadata=minimal
Accept: application/json
{
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Event",
"ConfirmationCode": "4372899DD",
"Description": "Client Meeting",
"Duration": "PT3H",
"EndsAt": "2014-06-01T23:11:17.5479185-07:00",
"OccursAt": {
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation",
"Address": "100 Church Street, 8th Floor, Manhattan, 10007",
"BuildingInfo": "Regus Business Center",
"City": {
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
"CountryRegion": "United States",
"Name": "New York City",
"Region": "New York"
}
},
"PlanItemId": 33,
"StartsAt": "2014-05-25T23:11:17.5459178-07:00"
}
Response Payload
Update a Derived Entity
The request below updates an event. Event derives from PlanItem.
PATCH serviceRoot/People('russellwhyte')/Trips(1003)/PlanItems(5)/Microsoft.OData.SampleService.Models.TripPin.Event
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Event",
"Description": "This is a new description"
}
Response Payload
Delete a Derived Entity
The request below deletes the flight plan item with Id '21' from a trip of person. Flight derives from PlanItem.
DELETE serviceRoot/People('russellwhyte')/Trips(1003)/PlanItems(21)/Microsoft.OData.SampleService.Models.TripPin.Flight
Response Payload
Containment Navigation Property
Containment navigation properties define an implicit entity set for each instance of its declaring entity type. This implicit entity set if identified by the read URL of the navigation property for that entity. The request below returns the contained navigation property Trips of entity set People.
Requesting a Contained Entity Set
The request below returns Trips for a person where Trips is a containment navigation property for Person.
GET serviceRoot/People('russellwhyte')/Trips
Response Payload
Create a Contained Entity
The request below creates a Trip for Person with UserName 'russellwhyte'. Trips is a contained navigation property for Person.
POST serviceRoot/People('russellwhyte')/Trips
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type" : "Microsoft.OData.SampleService.Models.TripPin.Trip",
"TripId" : 3,
"ShareId" : null,
"Description" : "Create Containment",
"Name" : "Test Trip",
"StartsAt" : "2014-01-01T00:00:00+08:00",
"EndsAt" : "2014-02-01T00:00:00+08:00",
"Budget" : 1000,
"Tags" : [
"Test Tag 1",
"Test Tag 2"
]
}
Response Payload
Filter on a Contained Entity Set
The request below returns Trips that contains 'New York' in its description of Person with UserName 'russellwhyte'.
GET serviceRoot/People('russellwhyte')/Trips?$filter=contains(Description, 'New York')
Response Payload
Update Contained Entity
The request below updates the contained Entity Trip.
PATCH serviceRoot/People('russellwhyte')/Trips(1001)
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Trip",
"Description": "This is a new description"
}
Response Payload
Delete Contained Entity
The request below deletes a contained Entity Trip.
DELETE serviceRoot/People('russellwhyte')/Trips(1001)
Response Payload
Open Type
OData V4 supports entity or complex types which allow clients to persist additional undeclared properties. Such entities and complex types are called open types.
Open Entity Type
When create or update an open entity, undeclared properties can be added.
The request below shows how to add an undeclared property Description when create the open entity Person.
POST serviceRoot/People
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
ETag: W/"08D15F3DD9126D84"
{
"@odata.type" : "Microsoft.OData.SampleService.Models.TripPin.Person",
"UserName": "teresa",
"FirstName" : "Teresa",
"LastName" : "Gilbert",
"Gender" : "Female",
"Description": "Big fan for travelling",
"Emails" : ["teresa@example.com", "teresa@contoso.com"],
"AddressInfo" : [
{
"Address" : "1 Suffolk Ln.",
"City" :
{
"CountryRegion" : "United States",
"Name" : "Boise",
"Region" : "ID"
}
}]
}
Response Payload
The request below shows how to add an undeclared property Description when update the open entity Person.
PATCH serviceRoot/People('keithpinckney')
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Person",
"Description": "Big fan for travelling"
}
Response Payload
Open Complex Type
OData V4 also supports open type for complex types.
The request below show how to add undeclared property Description when create new instance with AddressInfo of open complex type Location.
PATCH serviceRoot/People('russellwhyte')
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Person",
"AddressInfo@odata.type": "#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)",
"AddressInfo": [
{
"Address": "187 Suffolk Ln.",
"City": {
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
"CountryRegion": "United States",
"Name": "Boise",
"Region": "ID"
},
"Description": null
},
{
"Address": "XuanWu Load 555",
"City": {
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
"CountryRegion": "China",
"Name": "NanJing",
"Region": "JiangSu"
},
"Description": "Nice Location"
}
],
"Concurrency": 635393824693486800,
"Description": null,
"Emails@odata.type": "#Collection(String)",
"Emails": [
"Russell@example.com",
"Russell@contoso.com"
],
"FirstName": "Russell",
"Gender@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.PersonGender",
"Gender": "Male",
"LastName": "Whyte",
"UserName": "russellwhyte"
}
Response Payload
The request below show how to add undeclared property Description when update an instance with OccursAt of open complex type EventLocation.
PATCH serviceRoot/People('russellwhyte')/Trips(1003)/PlanItems(5)/Microsoft.OData.SampleService.Models.TripPin.Event
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json
{
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Event",
"OccursAt": {
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation",
"Address": "10 Beijing Street, 100000",
"BuildingInfo": "Beijing Restaurant",
"City": {
"@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City",
"CountryRegion": "China",
"Name": "Beijing",
"Region": "Beijing"
},
"Description": "Beautiful City."
}
}
Response Payload
Batch
Batch requests allow grouping multiple operations into a single HTTP request payload. The Batch request below contains the following operations in order listed:
1. A query request, returns all Airlines.
2. Create an entity, a new Airline.
3. A second query request Airlines.
POST serviceRoot/$batch
OData-Version: 4.0
Content-Type: multipart/mixed;boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: application/http
Content-Transfer-Encoding:binary
GET serviceRoot/Airlines HTTP/1.1
Accept: application/json;odata.metadata=minimal
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: application/http
Content-Transfer-Encoding:binary
Content-ID: 1
POST serviceRoot/Airlines HTTP/1.1
OData-Version: 4.0
Content-Type: application/json;odata.metadata=minimal
Accept: application/json;odata.metadata=minimal
{
"@odata.type" : "Microsoft.OData.SampleService.Models.TripPin.Airline",
"AirlineCode" : "EK",
"Name" : "Emirates Airline"
}
--batch_36522ad7-fc75-4b56-8c71-56071383e77b
Content-Type: application/http
Content-Transfer-Encoding:binary
GET serviceRoot/Airlines HTTP/1.1
Accept: application/json;odata.metadata=minimal
--batch_36522ad7-fc75-4b56-8c71-56071383e77b--
Response Payload