The Open Data Protocol (OData) enables the creation of REST-based data services, which allow resources, identified using Uniform Resource Identifiers (URIs) and defined in a data model, to be published and edited by Web clients using simple HTTP messages. This specification defines a set of recommended (but not required) rules for constructing URIs to identify the data and metadata exposed by an OData server as well as a set of reserved URI query string operators, which if accepted by an OData server, MUST be implemented as required by this document.
The [OData:Atom] and [OData:JSON] documents specify the format of the resource representations that are exchanged using OData and the [OData:Operations] document describes the actions that can be performed on the URIs (optionally constructed following the conventions defined in this document) embedded in those representations.
It is encouraged that servers follow the URI construction conventions defined in this specification when possible as such consistency promotes an ecosystem of reusable client components and libraries.
The terms used in this document are defined in the [OData:Terms] document.
A URI used by an OData service has up to three significant parts: the service root URI, resource path and query string options. Additional URI constructs (such as a fragment) MAY be present in a URI used by an OData service; however, this specification applies no further meaning to such additional constructs.
The following are two example URIs broken down into their component parts:
https://services.odata.org/OData/OData.svc _______________________________________/
| service root URI
https://services.odata.org/OData/OData.svc/Category(1)/Products?$top=2&$orderby=name
_______________________________________/ __________________/ _________________/
| | |
service root URI resource path query options
The service root URI identifies the root of an OData service. The resource identified by this URI MUST be an AtomPub Service Document (as specified in [RFC5023]) and follow the OData conventions for AtomPub Service Documents (or an alternate representation of an Atom Service Document if a different format is requested). OData: JSON Format specifies such an alternate JSON-based representation of a service document. The service document is required to be returned from the root of an OData service to provide clients with a simple mechanism to enumerate all of the collections of resources available for the data service.
| Example Request URI | OData Service URI |
|---|---|
| https://services.odata.org:8080 | https://services.odata.org:8080 |
| https://services.odata.org/OData/OData.svc/Categories | https://services.odata.org/OData/OData.svc/ |
The resource path construction rules defined in this section are optional. OData servers are encouraged to follow the URI path construction rules (in addition to the required query string rules) as such consistency promotes a rich ecosystem of reusable client components and libraries.
The resource path section of a URI identifies the resource to be interacted with (such as Customers, a single Customer, Orders related to Customers in London, and so forth). The resource path enables any aspect of the data model (Collections of Entries, a single Entry, Properties, Links, Service Operations, and so on) exposed by an OData service to be addressed.
The basic rules for addressing a Collection (of Entries), a single Entry within a Collection, as well as a property of an Entry are illustrated in the figure below.
For OData services conformant with the addressing conventions in this section, the canonical form of an absolute URI identifying a single Entry is formed by adding a single path segment to the service root URI. The path segment is made up of the name of the Collection associated with the Entry followed by the key predicate identifying the Entry within the Collection. For example the URIs https://services.odata.org/OData/OData.svc/Categories(1)/Products(1) and https://services.odata.org/OData/OData.svc/Products(1) represent the same Entry, but the canonical URI for the Entry is https://services.odata.org/OData/OData.svc/Products(1).
Examples
The example URIs below follow the addressing rules stated above and are based on the reference service and its service metadata document available at https://services.odata.org/OData/OData.svc/ and https://services.odata.org/OData/OData.svc/$metadata.
https://services.odata.org/OData/OData.svc/Categories
https://services.odata.org/OData/OData.svc/Categories(1)
https://services.odata.org/OData/OData.svc/Categories(1)/Name
https://services.odata.org/OData/OData.svc/Categories(1)/Products
https://services.odata.org/OData/OData.svc/Categories(1)/Products/$count
https://services.odata.org/OData/OData.svc/Categories(1)/Products(1)/Supplier/Address/City
https://services.odata.org/OData/OData.svc/Categories(1)/Products(1)/Supplier/Address/City/$value
Much like the use of links on Web pages, the data model used by OData services supports relationships as a first class construct. For example, an OData service could expose a Collection of Products Entries each of which are related to a Category Entry.
Associations between Entries are addressable in OData just like Entries themselves are (as described above). The basic rules for addressing relationships are shown in the following figure.
Examples
The example URIs below follow the addressing rules stated above and are based on the reference service and its service metadata document available at https://services.odata.org/OData/OData.svc/ and https://services.odata.org/OData/OData.svc/$metadata.
https://services.odata.org/OData/OData.svc/Categories(1)/$links/Products
https://services.odata.org/OData/OData.svc/Products(1)/$links/Category
OData services can expose Service Operations which, like Entries, are identified using a URI. Service Operations are simple functions exposed by an OData service whose semantics are defined by the author of the function. A Service Operation can accept primitive type input parameters and can be defined to return a single primitive, single complex type, collection of primitives, collection of complex types, a single Entry, a Collection of Entries, or void. The basic rules for constructing URIs to address Service Operations and to pass parameters to them are illustrated in the following figure.
Examples
The example URIs below follow the addressing rules stated above and are based on the reference service and its service metadata document available at https://services.odata.org/OData/OData.svc/ and https://services.odata.org/OData/OData.svc/$metadata.
https://services.odata.org/OData/OData.svc/ProductsByColor?color='red'
https://services.odata.org/OData/OData.svc/ProductsByColor(3)/Category/Name?color='red'
https://services.odata.org/OData/OData.svc/ProductsByColor?color='red'¶m=foo
https://services.odata.org/OData/OData.svc/ProductColors
The Query Options section of an OData URI specifies three types of information: System Query Options, Custom Query Options, and Service Operation Parameters. All OData services must follow the query string parsing and construction rules defined in this section and its subsections.
System Query Options are query string parameters a client may specify to control the amount and order of the data that an OData service returns for the resource identified by the URI. The names of all System Query Options are prefixed with a "$" character.
An OData service may support some or all of the System Query Options defined. If a data service does not support a System Query Option, it must reject any requests which contain the unsupported option as defined by the request processing rules in [OData:Operations].
A data service URI with a $orderby System Query Option specifies an expression for determining what values are used to order the collection of Entries identified by the Resource Path section of the URI. This query option is only supported when the resource path identifies a Collection of Entries.
The $orderby section of the normative OData specification outlines the full expression syntax supported by this query option. The examples below represent the most commonly supported subset of that expression syntax.
Examples
https://services.odata.org/OData/OData.svc/Products?$orderby=Rating
https://services.odata.org/OData/OData.svc/Products?$orderby=Rating asc
https://services.odata.org/OData/OData.svc/Products?$orderby=Rating,Category/Name desc
A data service URI with a $top System Query Option identifies a subset of the Entries in the Collection of Entries identified by the Resource Path section of the URI. This subset is formed by selecting only the first N items of the set, where N is an integer greater than or equal to zero specified by this query option. If a value less than zero is specified, the URI should be considered malformed.
If the data service URI contains a $top query option, but does not contain a $orderby option, then the Entries in the set needs to first be fully ordered by the data service. While no ordering semantics are mandated, to ensure repeatable results, a data service must always use the same semantics to obtain a full ordering across requests.
Examples
https://services.odata.org/OData/OData.svc/Products?$top=5
https://services.odata.org/OData/OData.svc/Products?$top=5&$orderby=Name desc
A data service URI with a $skip System Query Option identifies a subset of the Entries in the Collection of Entries identified by the Resource Path section of the URI. That subset is defined by seeking N Entries into the Collection and selecting only the remaining Entries (starting with Entry N+1). N is an integer greater than or equal to zero specified by this query option. If a value less than zero is specified, the URI should be considered malformed.
If the data service URI contains a $skip query option, but does not contain a $orderby option, then the Entries in the Collection must first be fully ordered by the data service. While no ordering semantics are mandated, to ensure repeatable results a data service must always use the same semantics to obtain a full ordering across requests.
Examples
https://services.odata.org/OData/OData.svc/Categories(1)/Products?$skip=2
https://services.odata.org/OData/OData.svc/Products?$skip=2&$top=2&$orderby=Rating
A URI with a $filter System Query Option identifies a subset of the Entries from the Collection of Entries identified by the Resource Path section of the URI. The subset is determined by selecting only the Entries that satisfy the predicate expression specified by the query option.
The expression language that is used in $filter operators supports references to properties and literals. The literal values can be strings enclosed in single quotes, numbers and boolean values (true or false) or any of the additional literal representations shown in the Abstract Type System section.
Note: The $filter section of the normative OData specification provides an ABNF grammar for the expression language supported by this query option.
The operators supported in the expression language are shown in the following table.
| Operator | Description | Example |
|---|---|---|
| Logical Operators | ||
| Eq | Equal | /Suppliers?$filter=Address/City eq 'Redmond' |
| Ne | Not equal | /Suppliers?$filter=Address/City ne 'London' |
| Gt | Greater than | /Products?$filter=Price gt 20 |
| Ge | Greater than or equal | /Products?$filter=Price ge 10 |
| Lt | Less than | /Products?$filter=Price lt 20 |
| Le | Less than or equal | /Products?$filter=Price le 100 |
| And | Logical and | /Products?$filter=Price le 200 and Price gt 3.5 |
| Or | Logical or | /Products?$filter=Price le 3.5 or Price gt 200 |
| Not | Logical negation | /Products?$filter=not endswith(Description,'milk') |
| Arithmetic Operators | ||
| Add | Addition | /Products?$filter=Price add 5 gt 10 |
| Sub | Subtraction | /Products?$filter=Price sub 5 gt 10 |
| Mul | Multiplication | /Products?$filter=Price mul 2 gt 2000 |
| Div | Division | /Products?$filter=Price div 2 gt 4 |
| Mod | Modulo | /Products?$filter=Price mod 2 eq 0 |
| Grouping Operators | ||
| ( ) | Precedence grouping | /Products?$filter=(Price sub 5) gt 10 |
In addition to operators, a set of functions are also defined for use with the filter query string operator. The following table lists the available functions. Note: ISNULL or COALESCE operators are not defined. Instead, there is a null literal which can be used in comparisons.
A URI with a $expand System Query Option indicates that Entries associated with the Entry or Collection of Entries identified by the Resource Path section of the URI must be represented inline (i.e. eagerly loaded). For example, if you want to identify a category and its products, you could use two URIs (and execute two requests), one for /Categories(1) and one for /Categories(1)/Products. The '$expand' option allows you to identify related Entries with a single URI such that a graph of Entries could be retrieved with a single HTTP request.
The syntax of a $expand query option is a comma-separated list of Navigation Properties. Additionally each Navigation Property can be followed by a forward slash and another Navigation Property to enable identifying a multi-level relationship.
Note: The $filter section of the normative OData specification provides an ABNF grammar for the expression language supported by this query option.
Examples
https://services.odata.org/OData/OData.svc/Categories?$expand=Products
https://services.odata.org/OData/OData.svc/Categories?$expand=Products/Suppliers
https://services.odata.org/OData/OData.svc/Products?$expand=Category,Suppliers
A URI with a $format System Query Option specifies that a response to the request MUST use the media type specified by the query option. If the $format query option is present in a request URI it takes precedence over the value(s) specified in the Accept request header. Valid values for the $format query string option are listed in the following table.
| $format Value | Response Media Type |
|---|---|
| Atom | application/atom+xml |
| Xml | application/xml |
| Json | application/json |
| Any other IANA-defined content type | Any IANA-defined content type |
| A service-specific value indicating a format specific to the specific OData service | Any IANA-defined content type |
Examples
https://services.odata.org/OData/OData.svc/Products?$format=atom
https://services.odata.org/OData/OData.svc/Products?$format=json
A data service URI with a $select System Query Option identifies the same set of Entries as a URI without a $select query option; however, the value of $select specifies that a response from an OData service should return a subset of the Properties which would have been returned had the URI not included a $select query option.
Version Note: This query option is only supported in OData version 2.0 and above.
The value of a $select System Query Option is a comma-separated list of selection clauses. Each selection clause may be a Property name, Navigation Property name, or the "*" character. The following set of examples uses the data sample data model available at https://services.odata.org/OData/OData.svc/$metadata to describe the semantics for a base set of URIs using the $select system query option. From these base cases, the semantics of longer URIs are defined by composing the rules below.
Examples
https://services.odata.org/OData/OData.svc/Products?$select=Price,Name
https://services.odata.org/OData/OData.svc/Products?$select=Name,Category
https://services.odata.org/OData/OData.svc/Products?$select=*
https://services.odata.org/OData/OData.svc/Categories?$select=Name,Products&$expand=Products
Note: The $select section of the normative OData specification provides an ABNF grammar for the expression language supported by this query option.
A URI with a $inlinecount System Query Option specifies that the response to the request includes a count of the number of Entries in the Collection of Entries identified by the Resource Path section of the URI. The count must be calculated after applying any $filter System Query Options present in the URI. The set of valid values for the $inlinecount query option are shown in the table below. If a value other than one shown in Table 4 is specified the URI is considered malformed.
Version Note: This query option is only supported in OData version 2.0 and above
| $inlinecount value | Description |
|---|---|
| allpages | The OData MUST include a count of the number of entities in the collection identified by the URI (after applying any $filter System Query Options present on the URI) |
| none | The OData service MUST NOT include a count in the response. This is equivalence to a URI that does not include a $inlinecount query string parameter. |
Examples
https://services.odata.org/OData/OData.svc/Products?$inlinecount=allpages
Custom Query Options provide an extension point for OData service-specific information to be placed in the query string portion of a URI. A Custom Query String option is defined as any name/value pair query string parameter where the name of the parameter does not begin with the "$" character. Any URI exposed by an OData service may include one or more Custom Query Options.
Examples
https://services.odata.org/OData/OData.svc/Products?x=y
Service Operations represent functions exposed by an OData service. These functions may accept zero or more primitive type parameters. If a Service Operation requires an input parameter those parameters are passed via query string name/value pairs appended to the URI which identify the Service Operation as described in the Addressing Service Operations section. For nullable type parameters, a null value may be specified by not including the parameter in the query string of the URI.
Examples
https://services.odata.org/OData/OData.svc/GetProductsByRating?rating=5
When determining if two URIs are equivalent, each URI SHOULD be normalized using the rules specified in [RFC3987] and [RFC3986] and then compared for equality using the equivalence rules specified in HTTP [RFC 2616], Section 3.2.3.