OData V4 Concepts
A minimal primer for PHP developers who have never worked with OData.
What is OData?
OData (Open Data Protocol) is a REST-based protocol for querying and manipulating data. It defines a standard URL syntax for filtering, sorting, paging, and selecting data, plus a machine-readable schema format (CSDL) that describes the data model.
OData is to REST APIs what SQL is to databases: a standard query language that any client can speak without custom documentation.
Core concepts
Entity Type
An entity type is a named structured type with an identity (a key). It maps to a database table or model class.
EntityType: Product
Key: id (Edm.Int64)
Properties:
id Edm.Int64
name Edm.String
price Edm.Decimal
active Edm.BooleanEntity Set
An entity set is a named, addressable collection of entity instances. It maps to a queryable endpoint.
EntitySet: Products → EntityType: Product
URL: /odata/ProductsProperty
A structural property holds a data value. OData defines primitive types:
| OData Type | PHP Equivalent | DB Example |
|---|---|---|
Edm.String | string | VARCHAR, TEXT |
Edm.Int32 | int | INTEGER |
Edm.Int64 | int | BIGINT |
Edm.Double | float | FLOAT, DOUBLE |
Edm.Decimal | string | DECIMAL |
Edm.Boolean | bool | BOOLEAN |
Edm.Date | string | DATE |
Edm.DateTimeOffset | string | DATETIME, TIMESTAMP |
Edm.TimeOfDay | string | TIME |
Edm.Guid | string | UUID |
Edm.Binary | string | BLOB |
Navigation Property
A navigation property represents a relationship between two entity types. It maps to an Eloquent relationship.
EntityType: Flight
NavigationProperty: passengers → Collection(Passenger)
EntityType: Passenger
NavigationProperty: flight → FlightComplex Type
A complex type is a structured value without identity (no key). It is used for nested data like an address or a monetary amount.
Function
A function is a named, side-effect-free operation that returns a value. Functions can accept parameters.
Function: GetFlightCount() → Edm.Int32
Function: GetFlightsByOrigin(origin: Edm.String) → Edm.Int32Singleton
A singleton is a named single entity instance (not a collection). It is used for application settings or the current user.
Query options
OData defines system query options that clients append to the URL:
| Option | Purpose | Example |
|---|---|---|
$filter | Filter rows | $filter=price gt 10 |
$select | Choose columns | $select=name,price |
$expand | Include related data | $expand=passengers |
$orderby | Sort results | $orderby=name asc |
$top | Limit result count | $top=10 |
$skip | Skip rows (offset) | $skip=20 |
$count | Include total count | $count=true |
$search | Free-text search | $search=widget |
$compute | Add computed columns | $compute=price mul 1.1 as taxed |
Metadata
Every OData service exposes a machine-readable schema at $metadata:
GET /odata/$metadataThis returns CSDL XML describing all entity types, properties, relationships, and functions. UI5 SmartControls consume this metadata to auto-generate forms, tables, and filters.
Service document
The service root returns a JSON listing of all available entity sets:
GET /odata{
"@odata.context": "http://localhost/odata/$metadata",
"value": [
{"name": "Products", "kind": "EntitySet", "url": "Products"}
]
}