Skip to main content

OData Version 4.0 is the current recommended version of OData. OData V4 has been standardized by OASIS and has many features not included in OData Version 2.0.

Go to OData Version 4.0

Introduction

OData supports two formats for representing the resources (Collections, Entries, Links, etc) it exposes: the XML-based AtomPub format and the JSON format. This document describes how OData resources are represented in JSON and [OData-Atom] describes the AtomPub 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.

1. Background

JavaScript Object Notation (JSON) is a lightweight data interchange format based on a subset of the JavaScript Programming Language standard, as specified in [ECMA-262]. JSON is a text format that is language independent, but uses conventions that are familiar to programmers of the C-family of languages (C, C++, JavaScript, and so on). OData supports the JSON format to make consuming OData services from Javascript applications simple since JSON can be easily be turned into JavaScript objects for programmatic manipulation using the Javascript eval( ) function.

2. Terminology

A full list of terms used by the Open Data Protocol is available on the OData Glossary of Terms page.

3. JSON Representations

The following sections define how resources exposed by an OData service can be represented in requests and/or responses payloads using the JSON format. For details regarding how to create various request types (Retrieve, Create, etc) see [OData-Operations] . Security Note: In responses payloads (not request payloads) all the JSON representations described in this section are wrapped by an outer most object that includes a single name/value pair. The name of the name/value pair is always "d" and the value is the JSON representation of an OData resource as described by the subsections of this document. This pattern ensures JSON payloads returned from OData services are valid JSON statements, but not valid JavaScript statements. This prevents an OData JSON response from being executed as the result of a cross site scripting (XSS) attack.

4. Primitive Types

Values of an OData primitive type are represented as JSON literal values as per the table below. Note: The type system used by OData services is described in full in the Abstract Type System section of the [OData-Core] document.

Primitive Type JSON Serialization Format
Edm.Binary Base64 encoded value of an EDM.Binary value represented as a JSON string
Edm.Boolean true | false
Edm.Byte Literal form of Edm.Byte as used in URIs formatted as a JSON string
Edm.DateTime "/Date(<ticks>["+" | "-" <offset>)/"<ticks> = number of milliseconds since midnight Jan 1, 1970<offset> = number of minutes to add or subtract
Edm.Decimal Literal form of Edm.Decimal as used in URIs formatted as a JSON string
Edm.Double Literal form of Edm.Double as used in URIs formatted as a JSON string
Edm.Guid Literal form of Edm.Guid as used in URIs formatted as a JSON string
Edm.Int16 A JSON number
Edm.Int32 A JSON number
Edm.Int64 A 64-bit integer formatted as a JSON string
Edm.SByte Literal form of Edm.SByte as used in URIs formatted as a JSON string
Edm.Single Literal form of Edm.Single as used in URIs formatted as a JSON string
Edm.String Any JSON string
Edm.Time Literal form of Edm.Time as used in URIs formatted as a JSON string
Edm.DateTimeOffset Literal form of Edm.DateTimeOffset as used in URIs formatted as a JSON string

5. Service Documents

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 represented in JSON by an object with a single name/value pair with the name equal to "EntitySets" and the value being an array of Collection names. For example a service document with three collections would be formatted as:

{ "d" : { "EntitySets": ["Products", "Categories", "Suppliers"] } }

6. Representing Collections of Entries

Collections represent a set of Entries. In OData v1, Collections are represented as an array of objects, with one object for each Entry within the Collection. For example, a collection of Entries would be represented as shown below. The format of each object in the array is described in the Representing Entries section. In OData v2, Collections are still represented as arrays, however to enable representing Collection-level metadata, the array of objects representing the set of Entries is included as the value of a "results" name/value pair.

OData V1: { 
  "d" : [ 
    { ... }, 
    { ... }, 
    { ... }, 
  ] 
} 
OData V2: { 
  "d" : { 
    "results":  [ 
      { ... }, 
      { ... }, 
      { ... }
    ] 
  }
}

OData v2 supports two pieces of collection-level metadata: an Entry count (the 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 representation when a Collection of entries is being returned by an OData service and the request URI included the $inlinecount System Query Option. In this case, the count information is represented as a name/value pair with name equal to "count" and the value being the number of Entries in the collection. See ; $inlinecount section of the [OData-URI] document for a description of how the count value is calculated. In response payloads, representing Collections of Entries, if the server does not include an object for every Entry in the Collection of Entries identified by the request URI then the response represents a partial listings of the Collection. In this case, "__next" name/value pair is included to indicate the response represents a partial listing. The value of the name/value pair is a URI which identifies the next partial set of entities from the originally identified complete set. For more information on interacting with partial listings, see Retrieving feeds, entries and service documents in the [OData-Operations] document.

OData V2: { 
  "d" : { 
    "results": [ { 
      "__metadata": { 
        "uri": "https://services.odata.org/OData/OData.svc/Categories(0)",
        "type": "DataServiceProviderDemo.Category" }, "ID": 0, "Name": "Food", 
        "Products": { 
          "__deferred": { 
            "uri": "https://services.odata.org/OData/OData.svc/Categories(0)/Products"
          } 
        } 
      }, 
      { /* another Category Entry */ }, 
      { /* another Category Entry */ }, 
      { /* another Category Entry */ } 
    ], 
    "__count": "3", 
    "__next": "https://services.odata.org/OData/OData.svc$skiptoken=12"
  } 
}

7. Representing Entries

In OData v1, Entries are represented as JSON objects with all the properties of the Entry represented as name/value pairs of the object. Alternatively, if the Entry is being represented was identified with a URI that includes a Select System Query Option, then the prior rule is relaxed such that only the properties identified by the $select query option are represented as name/value pairs. OData v2 represents Entries the same way as V1. An optional "__metadata" name/value pair is the only pair that should be included on the object that does not directly represent a Property of the Entry being represented. This name/value pair is not data, but instead, by convention defined in this document, specifies the metadata for the Entry being represented. The value of the "__metadata" name/value pair is a JSON object that contains the name/value pairs described in the table below.

"__metadata" object name/value pairs Optional Description
uri No The canonical URI identifying the Entry being represented
type Yes* The name of the EntityType in the data model of the OData service that describes the Entry being represented.*This name/value pair must be included if the Entry being represented is part of a type hierarchy and is not the base type in the hierarchy.
etag Yes The concurrency token associated with the Entry being represented
edit_ media, media_src, media_etag, content_type -- These name/value pairs only apply if the Entry is a Media Link Entry as described by the Representing Media Link Entries section.

For example, a single Category Entry would be represented as shown in the example below.

OData V1: { 
  "d" : { 
    "__metadata": { 
      "uri": "https://services.odata.org/OData/OData.svc/Categories(0)",
      "type": "DataServiceProviderDemo.Category" 
    }, 
    "ID": 0, 
    "Name": "Food", 
    "Products": { 
      "__deferred": { 
        "uri": "https://services.odata.org/OData/OData.svc/Categories(0)/Products"
      } 
    } 
  }
} 
OData V2: { 
  "d" : { 
      "__metadata": { 
        "uri": "https://services.odata.org/OData/OData.svc/Categories(0)",
        "type": "DataServiceProviderDemo.Category" 
      }, 
      "ID": 0, 
      "Name": "Food", 
      "Products": { 
        "__deferred": { 
          "uri": "https://services.odata.org/OData/OData.svc/Categories(0)/Products"
        } 
      } 
  } 
}

8. 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 an Entry or Collection of entries as 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 above, by default properties which represent Links (the "Products" property in the example) are represented as an object with a "__deferred" name/value pair to indicate the service deferred representing the related Entries. The uri name/value pair within the "__deferred" object must be provided and can be used to retrieve the deferred content.

9. 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. For example, a single Category Entry with its related Product Entries serialized inline as shown in the example below.

OData V1 and V2: { 
  "d" : { 
    "__metadata": { 
      "uri": "https://services.odata.org/OData/OData.svc/Categories(0)",
      "type": "DataServiceProviderDemo.Category" }, 
      "ID": 0,
      "Name": "Food", 
      "Products": [ { 
        "__metadata": { 
          "uri": "https://services.odata.org/OData/OData.svc/Products(0)",
          "etag": "W/"0"", 
          "type": "DataServiceProviderDemo.Product" 
        }, 
        "ID": 0, 
        "Name": "Bread", 
        "Description": "Whole grain bread", 
        "ReleaseDate": "/Date(694224000000)/",
        "DiscontinuedDate": null, 
        "Rating": 4, 
        "Price": "2.5", 
        "Concurrency": 0, 
        "Category": { 
          "__deferred": { 
            "uri": "https://services.odata.org/OData/OData.svc/Products(0)/Category"
          } 
        }, 
        "Supplier": { 
          "__deferred": { 
            "uri": "https://services.odata.org/OData/OData.svc/Products(0)/Supplier"
          } 
        } 
      } 
    ] 
  } 
} 

10. Representing Media Link Entries

Media Link Entries (MLE) are represented in the same way as "plain" Entries as described in Representing Entries; however, they also contain additional metadata per Entry that describes the Media Resource (MR) associated with the Entry. This additional MR metadata is represented as name/value pairs of the "__metadata" object associated with the Entry.

"__metadata" object name/value pairs for MLEs Optional Description
media_src No The URI to use when retrieving the Media Resource
edit_ media Yes The URI to use when editing the Media Resource
media_etag Yes The concurrency token for the Media Resource
content_type No The IANA media type of the Media Resource (ex. image/jpeg )

11. 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 JSON.

12. 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 JSON as a name/value pair, with the name equal to the name of the property and primitive type value formatted as described by the table in the Primitive Types section above. Starting with OData V2, 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 the value of a "results" name/value pair. For example, the response payload to a retrieve request that identifies the Name property of a Category Entry is represented as shown below.

OData V2 Response Payload: { "d" : { "results": { "Name": "Bread" }

13. Representing Complex Types Properties

When represented as a property of an Entry or Complex Type in a request/response payload, a property whose type is a complex type is represented as a JSON object with each property of the complex type represented as a name/value pair (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. Starting with OData V2, in response payloads only, 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 is represented as the value of a "results" name/value pair. For example, the response payload to a retrieve request that identifies the Name property of a Category Entry is represented as shown below.

OData V2 Response Payload: { 
  "d" : { 
    "results": { 
      "__metadata": { 
        "type": "DataServiceProviderDemo.Address"
      }, 
      "Street": "NE 228th", 
      "City": "Sammamish", 
      "State": "WA", 
      "ZipCode": "98074",
      "Country": "USA" 
    } 
  } 
}

14. Representing the Raw value of a Property

OData services may support addressing the "raw" 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 "raw" 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.

HTTP/1.1 200 OK DataServiceVersion: 1.0; Content-Type: text/plain;charset=utf-8
  Food

15. 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 Entities. A single link is represented as a JSON object with a "uri" name/value pair with the value of the pair being the URI that identifies the Link. A collection of links is represented as a array of JSON objects with each object representing a Link. For example, a link with multiplicity 1 (ex. Product is related to a single Supplier) would be represented in a response as:

{ "d" : { "uri": "https://services.odata.org/OData/OData.svc/Suppliers(0)" } }

For example, a link with multiplicity greater than 1 (ex. Supplier is related to many products) would be represented in a response as:

OData V1 Response Payload: { 
  "d" : [ 
    { "uri": "https://services.odata.org/OData/OData.svc/Products(0)" }, 
    { "uri": "https://services.odata.org/OData/OData.svc/Products(7)" }, 
    { "uri": "https://services.odata.org/OData/OData.svc/Products(8)" } 
  ]
} 
OData V2 Response Payload: { 
  "d" : { 
    "results": [ 
      { "uri": "https://services.odata.org/OData/OData.svc/Products(0)" }, 
      { "uri": "https://services.odata.org/OData/OData.svc/Products(7)" }, 
      { "uri": "https://services.odata.org/OData/OData.svc/Products(8)" } 
    ], 
    "__count": "3" 
  } 
}

16. Representing Results from Service Operations

As described in [OData-Operations] OData service may expose custom behaviors via Service Operations. As described in [OData-URI] the input parameters to Service Operations are identified by the request URI. This section specifies how the results of a Service Operation are formatted using JSON. Service operations support returning:

If a Service Operation returns a collection of Entries or a single Entry, then the Entries (or Entry) are formatted in the same way as described in the Representing Collections of Entries or Representing an Entry section. If a Service Operation returns a single primitive value, then it is formatted as per the Representing Primitive Properties section. Likewise, if a Service Operation returns a single Complex Type value, then it is represented as per the Representing Complex Type Properties section. If a Service Operation returns a collection of primitive values, then the primitives are returned as a JSON array as shown in the example below.

{ "d" : [ 0, 1, 2 ] }

If a Service Operation returns a collection of complex types, then a JSON array of objects are returned, one object per complex type. Each complex type is represented as described in the Representing Complex Type Properties section above.