OData supports two formats for representing the resources (Collections, Entries, Links, etc) it exposes: the XML-based Atom format and the JSON format. This document describes how OData resources are represented in Atom (plus additional elements defined in AtomPub) and [OData-JSON] describes the JSON representation. The content type negotiation section of the [OData-Operations] document describes how clients can use standard HTTP content type negotiation to tell an OData service which format it wants to use.
As described in Atom [RFC4287], Atom is an XML-based document format that describes Collections of related information known as "feeds". Feeds are composed of a number of items, known as Entries. AtomPub [RFC5023] defines additional format constructs for Entries and Feeds to enable the resources they represent to be easily categorized, grouped, edited and discovered. For the remainder of this document, the term Atom is used to represent the combination of the format/representation rules defined in Atom[RFC4287] and AtomPub [RF5023].
As noted in the OData Basics section of [OData:Core], OData services expose Collections of structured Entries, making Atom a natural fit for representing OData resources. Since Atom does not define how structured data is encoded with feeds, to enable transfers of structured content by OData services, this document defines a set of conventions for representing structured data in an Atom feed.
It should be noted that feeds following the conventions defined in this document are valid AtomPub feeds and can be consumed by feed readers, tools, etc. which are only aware of the Atom standards ([RFC4287] & [RFC5023]), but not the additional conventions defined in this document.
2. Atom Representations
The following sections define how resources (Collection, Entries, etc) exposed by an OData service can be represented in requests and responses payloads using the Atom format. For details regarding how to create various request types (Retrieve, Create, etc) see [OData-Operations] .
Through out this section the notation is used to refer to the named element in the Atom [RFC4287] specification.
2.1. Primitive Types
Values of OData primitive types are represented as values of XML elements/attributes as per the table below. Note: The type system used by OData services is described in full in the primitive types section of the [OData-Core] document. In addition to the rules stated in the table, if the value of a primitive type is null, then it is represented as an empty XML element with an m:null="true" attribute ("m" identifies the OData metadata namespace).
Serialization Format in XML Documents
Base64 encoded value of an EDM.Binary value. See [RFC3548] .
As described in [OData-Core], if a service exposes several Collections, then to aid discovery of those Collections by clients it is useful for the service to expose a Service Document which lists the available Collections. Service Documents are described in AtomPub [RFC5023], section 15.
For example, the URI https://services.odata.org/OData/OData.svc identifies the Service Document of a sample OData service which exposes a Categories, Products and Suppliers Collection. For convenience, a sample Service Document is shown in the listing below.
2.3. Representing Collections of Entries
Collections represent a set of Entries. In OData, Collections are represented as Atom feeds ([RFC5023] ), with one Atom entry for each Entry within the Collection. For example, a Collection of product category Entries (that could be part of a product catalog) exposed by an OData service, as identified by the URI https://services.odata.org/OData/OData.svc/Categories, is represented as shown below. The format of elements within a feed is described in the Representing Entries section.
Note: The "m" and "d" prefixes represent the OData metadata and data namespaces. It is likely the next version of OData will generalize the namespace URI to use an odata.org based URI.
In response payloads only, OData v2 supports two pieces of collection-level metadata: an Entry count (the total count of the number of entities in the Collection) and "next links" in the case when a partial listing of the Collection of Entries is being represented.
The Entry count, is only included in the feed returned by an OData service when the request URI includes the $inlinecount System Query Option. In this case, the count information is represented as a element with the value of the element being the total number of Entries in the Collection. See the $inlinecount section of the [OData-URI] document for a description of how the count value is calculated.
In response payloads only, if the server does not include an element for every Entry in the Collection identified by the request URI (typically for resource conservation reasons), then the returned feed represents a partial listing as defined in AtomPub [RFC5023] section 10.1. In this case, the response includes a element to indicate the feed is a partial listing and to provide the URI of the next partial list feed so a client can easily continue obtaining additional entries. Version Note: Partial lists of Entries are supported in OData V2.0 only. For more information on interacting with partial listings, see Retrieving feeds, entries and service documents in the [OData-Operations] document.
2.4. Representing Entries
In OData, Entries are represented as Atom elements with all the Properties of the Entry represented as elements within the element which is a direct child of the element. When using an OData v2 server, clients may indicate that they want a subset of the properties by using the Select System Query Option in the request.
If the Entry being represented links to other Entries via Navigation Properties (e.g. a Product is related to a Category), then the Links are represented as
Metadata describing the Entry being represented can be specified using additional Atom-defined and OData-defined elements/attributes as defined by the following list.
As per [RFC4287], contains a URI which uniquely identifies the Entry
This element may be present with a term attribute whose value indicates the Entity Type in the data model of the OData service that describes the Entry represented by the parent element. An must contain at most one such category element with the specified scheme.
To ensure type fidelity across of Entries sent from server to client (and vice versa), this element must be included if the Entry is part of a type hierarchy and is not the base type in the hierarchy.
When this element is not present clients and servers should assume that the entry is of the base type of the containing collection, if that information is known. When a collection can contain a number of types within a inheritance hierarchy servers will typically reject requests that contain Entries without type information.
As per [RFC4287], this element is optional. If included it contains the URI a client should use to retrieve the Entry as described in [OData-Operations] .
As per [RFC5023], this element should be included. If included it contains the URI a client should use to update or delete the Entry as defined in [OData-Operations] .
An attribute in the OData Metadata Namespace whose value is the concurrency token associated with the Entry. The value is formatted as required by the ETag header in [RFC2616].
This attribute should be present in a response from an OData service when returning a feed (i.e. multiple Entries in a single HTTP response), otherwise the HTTP ETag response header should be used to communicate the concurrency token of the resource returned to a client.
For example, as shown in the following listing, the Category Entry identified by the URI https://services.odata.org/OData/OData.svc/Categories(0), has two primitive properties (ID & Name) and one Navigation Property named â€œProductsâ€, which identifies a feed of Product Entries related to the Category.
2.4.1. Deferred Content
To conserve resources (bandwidth, CPU, and so on), it is generally not a good idea for an OData service to return the full graph of Entries related to the Entry (or Collection of entries) identified in a request URI. For example, an OData service should defer sending related Entries unless the client explicitly asked for them using the $expand System Query Option which provides a way for a client to state related entities should be represented inline.
As shown in the example in the prior section, by default properties which represent Links (the "Products" property in the example) are represented as a element to indicate the service deferred representing the related Entries. If needed, a client can then use the URI in the href attribute in a subsequent retrieve request to obtain the related Entries.
2.4.2. Inline Representation of Associated Entries
As described in the $expand System Query Option section of the [OData-URI] document, a request URI may include the $expand query option to explicitly request that a linked to Entry or collection of Entries be serialized inline, rather than deferred.
In this case the related Entry or collection of Entries is represented as the child element of an element as an or respectively. For example, a single Category Entry with its related Product Entries serialized inline is represented as shown in the example below.
2.4.3. Representing Media Link Entries
Media Link Entries (MLE) are represented in the same way as regular Entries as described in Representing Entries; however, they also contain additional metadata per Entry that describes the Media Resource (MR) associated with the Entry and the element becomes a child of the element. The element is moved out from under the element because in the case of an MLE, the content describes the MR.
This additional MR-specific metadata is represented by the following constructs in the :
If the ETag of the Media Resource (MR) is independent from that of the Media Link Entry (MLE), then this element should include an m:etag attribute with value equal to the concurrency token of the MR.
For MLE's, this element describes the associated MR. The value of the src attribute is the URI a client should use to retrieve the Media Resource, as described in [OData-Operations]. Note: this allows a Media Resource to have independent links for editing and retrieval.
The value of the type attribute is the mime type of the MR.
2.4.4. Customizing the Representation of an Entry
Services may wish to have more flexibility over how Entries are represented within an element. For example, a service may want to enable the value of a property of an Entry be represented as the value of one of the standard Atom elements (Title, Summary, etc) or as the value of a custom element within an Entry. OData supports services that need this kind of control over the Atom representations of an Entry.
In general a service may choose to deviate from the conventions defined in Representing Entries section above and represent the value of a Property of an Entry as the value of a standard Atom element (Title, Summary, etc) or as the value of an element in a custom namespace. When a service does this form of customization it breaks the shared assumption between client and server regarding how Entries are encoded within an element. OData services that deviate from the prescribed encoding should expose a Service Metadata Document that include Feed Customization annotations which allow a client to discover how the server chose to encode a given Entry within the element. The remainder of this section describes the set of Feed Customization annotations that may be used.
The following table lists all the Feed Customization annotations defined in OData.
Feed Customization Annotation
The name of the Property on an Entry which this feed mapping rule applies to.The format of this parameter is a path expression where property names are separated by a / character. For example for a Person Entry with an integer Property Age and an Address Complex Type Property, the following are legal values for this property:
The following are invalid values for this property:
- Foo (not a defined property)
- Address (doesn't identify a primitive property)
- Address/Street/ (cannot end with a /)
- Empty string or null
- /Address/Street (cannot start with a /)
The name of the element to map the property identified by the FC_SourcePath annotation to. If no FC_SourcePath annotation is specified, then this annotation must be on a element in the Service Metadata Document which itself identifies the source Property.The format of this annotation is a path expression where nested elements are separated by a / and attributes are specified by a @ symbol.
For example, to map to a property value to a custom XML element or attribute:
To map the source Property to a custom element which is a direct child of the element use:
To map the source Property to an attribute named Term on a custom element which is a direct child of the element:
To map the source Property to a child element of the custom element named , where is a direct child of the element:
This annotation also supports mapping to Atom-defined elements. This following list describes the values used to map to Atom-defined elements:
Format: value : mapped to atom element
Note: This annotation does not support mapping to multiple instances of an element, so two overlapping path definitions imply the same element instances. For example: the target path values a/b/c and a/d/f imply the following XML structure:
The mime type of the source Property
When the source Property is being mapped to an element that is not in the Atom namespace, the value of this annotation specifies the namespace prefix to use the Atom document for target element.
When a property is being mapped to an element that is not in the Atom namespace, this annotation is used to specify the namespace for the target element. The FC_NSPrefix annotation specifies the namespace prefix for the namespace specified by this annotation.
The value of this property is true if the property being mapped should appear both in its â€œmapped toâ€ location as well as within the content section of the .If the value of this property is false, then the property being mapped should only appear in its new â€œmapped toâ€ location in the and NOT also in the content section. This value (false) is only supported in OData v2.0 and requires that any response formatted in this way return a DataServiceVersion:2.0 response header.
For example, the sample Service Metadata Document at https://services.odata.org/OData/OData.svc/$metadata states the Name Property of the Category Entry is represented as the value of the element. Since FC_KeepInContent is equals true for this mapping the value is duplicated within the element.
If the Category Entry in the example above was part of a type hierarchy and the Name property was defined on the type Category derives from, then the mapping from Name to is still possible, however the placement of the annotation changes to be on the element in the Service Metadata Document as shown in the following listing.
Instead of mapping the Name property to an Atom-defined element, a Property may be mapped to a custom element in any namespace. For example, the following listing maps the Street Property of the Address Complex Type on a Supplier entry to a custom element.
2.5. Representing Primitive Properties
When represented in a request/response payload as part of an Entry, Complex Type or a standalone construct in a request payload, primitive properties are represented in Atom as child elements of an element (see Representing Entities) with the name equal to the element equal to the property and value of the element set to the primitive type value formatted as described by the table in the Primitive Types section above.
See section 3.1 for the format of Properties when they are represented independently from their defining Entry (i.e. outside the context of the defining Entry).
2.6. Representing Complex Type Properties
When represented as a property of an Entry or Complex Type (also within an Entry) in a request/response payload, a property whose type is a complex type is represented as an XML element with each property of the complex type represented as a direct child element (as described in the prior section for primitive properties). For example, the Address Complex Type of a Supplier Entry is shown in the example below.
See section 3.1.2 for the format of Complex Type Properties when they are represented independently from their defining Entry (i.e. outside the context of the defining Entry).
3. XML Representations
The smallest unit of information that can be represented in Atom is an Entry. In several application scenarios it is practical to be able to identify a specific piece of information within the Entry, particularly when the entry is mapped to an application-level construct on the server. For example, a Presentation Entry may have a Property that is the abstract describing the presentation.
To enable this scenario, as described in the Resource Path section in the [OData-URI] document, OData supports directly addressing a Property of an Entry. Since there is not a natural mapping of a single Property (outside of the context of the defining Entry) to an Atom representation, OData represents the constituent parts of an Entry using a simple XML representation, which is described by the following subsections.
3.1. Representing Property Values
As described in the Resource Path section in the [OData-URI] document, OData supports directly addressing a Property of an Entry. The following subsections describe how each type of Property is represented in XML.
3.1.1. Representing Primitive Properties
When a primitive Property is represented as a standalone construct in a response from an OData service (such as when a retrieve request is made to a URI that identifies a single Property) it is represented as a single XML element where the element name equals the name of the Property and the value of the element is the value Property value. For example, the response payload to a retrieve request that identifies the Name property of a Category Entry is represented as shown below.
3.1.2. Representing Complex Types Properties
When a Property whose type is a complex type is represented as a standalone construct, such as when a retrieve request is made to a URI that identifies a single Property, it uses a single XML element with the name of the Property and child elements for each Property defined on the complex type (formatted as per this section of the prior â€œRepresenting Primitive Propertiesâ€ section). For example, the response payload to a retrieve request that identifies the Name property of a Category Entry is represented as shown below.
3.1.3. Representing the Raw value of a Property
OData services may support addressing the entry value of a primitive Property (see the description of the $value URI segment). In this case, the value is returned using the format (aka mime type) the OData service deems to be the entry format for the Property. For example, the HTTP response from the sample OData service when retrieving the Name string Property of a Category Entry is shown in the example below.
3.2. Representing Links
A Link (or collection of Links) represents an associated Entry (or collection of associated Entries). As described in [OData-Operations] Links can be retrieved and modified to change the associations between Entries. A single link is represented as a element with the value of the element set to the URI that identifies the Link. A collection of links is represented as a element with zero or more child elements, where each element represents a Link.
For example, a link with multiplicity 1 (ex. Product is related to a single Supplier) would be represented in XML in a response as:
For example, a link with multiplicity greater than 1 (e.g. Supplier is related to many products) would be represented in a response as:
3.3. Representing Results from Service Operations
As described in [OData-Operations] OData services may expose custom behaviors via Service Operations, which may accept input parameters identified by the request URI (as described in [OData-URI]). This section specifies how the results of a Service Operation are formatted using Atom or XML. Service operations support returning:
A single primitive value or collection of primitive values
A single complex type or collection of complex types
If a Service Operation returns a collection of primitive values, then the primitives are returned as the value of elements which are children of the root element. The name of the root element should be equal to the name of the Service Operation that was invoked. For example a response payload from a "GetInts" Service Operation that returns a collection of integer values would be formatted as shown in the following listing.
If a Service Operation returns a collection of complex types, then the collection is represented in XML by a root element whose name is equal to the name of the Service Operation and includes one child element for each Complex Type value in the collection returned from the Service Operation. The Properties of each Complex Type are represented as per the Representing Complex Type Properties section. Finally, each element should include an m:type attribute that lists the namespace qualified name of the Complex Type. For example, response payload from a "GetAddresses" Service Operation that returns a collection of Address Complex Type values would be represented as show in the following listing.