Top Banner
OPEN DATA PROTOCOL (ODATA) DEEP DIVE A common, open, RESTful Web protocol for querying and updating data that provides a uniform way to unlock data and free it from silos that exist in applications today.
62

Open Data Protocol (OData) Deep Dive

Feb 25, 2016

Download

Documents

mimis

Open Data Protocol (OData) Deep Dive. A common, open, RESTful Web protocol for querying and updating data that provides a uniform way to unlock data and free it from silos that exist in applications today. OData. = REST Resource-oriented Entities modeled as URI-addressable Resources - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Open Data Protocol (OData) Deep Dive

OPEN DATA PROTOCOL (ODATA)DEEP DIVE

A common, open, RESTful Web protocol for querying and updating data that provides a uniform way to unlock data and free it from silos that exist in applications today.

Page 2: Open Data Protocol (OData) Deep Dive

ODATA

= REST• Resource-oriented

o Entities modeled as URI-addressable Resourceso Relationships modeled as links (URIs)o CRUD = POST, GET, PUT/PATCH, DELETE

• Hypermedia-driveno Navigate from Service Document to Sets to Members to related items to…o Links in Payload for editing, navigation, operations, etc.

+ Data Model• URLs, operations, namespaces, derived from declarative model

+ Common Conventions• Common query string options• Representation within Formats

+ Common Formats• ATOM, JSON

Page 3: Open Data Protocol (OData) Deep Dive

USE OF HTTP

• HTTP Methods• GET, POST, PUT/PATCH, DELETE

• HTTP Headers• Content Negotiation

o Accept, Accept-Charset, Accept-Encoding, Accept-Languageo Content-Type, Content-Length, Content-Encoding, Content-

Language• Concurrency

o Etags, If-Match, If-None-Match• Etc…

• HTTP Result Codes• 2xx Success Codes• 3xx Redirection• 4xx Client Error Messages

Page 4: Open Data Protocol (OData) Deep Dive

ODATA FEATURE AREAS

• Versioning• Service Metadata• Data Requests• Data Modification• Relationships• Content Types• Extensibility

Page 5: Open Data Protocol (OData) Deep Dive

VERSIONING

Page 6: Open Data Protocol (OData) Deep Dive

PROTOCOL VERSIONING• DataServiceVersion header• Describes the protocol version according to which

the request/response should be interpreted• MaxDataServiceVersion Request Header• The maximum protocol version that the client can

accept• MinDataServiceVersion Request Header• The minimum protocol version the client can

accept

-Clients SHOULD specify a MaxDataService-Services return a response formatted according to the latest protocol version the service supports that is less than MaxDataServiceVersion but at least MinDataServiceVersion

Page 7: Open Data Protocol (OData) Deep Dive

SCHEMA VERSIONING

• When a data model or other breaking change is made to the service, the service URL is generally versioned. For example:• odata.netflix.com/v1/Catalog • odata.netflix.com/v2/Catalog

Page 8: Open Data Protocol (OData) Deep Dive

SERVICE METADATA

Page 9: Open Data Protocol (OData) Deep Dive

SERVICE DOCUMENT

• Root of service exposes a “Service Document”• Describes collections of EntitiesGET /odata.netflix.com/v2/Catalog HTTP/1.1

<service xmlns="http://www.w3.org/2007/app" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xml:base="http://odata.netflix.com/v2/Catalog/"> <workspace> <atom:title>Default</atom:title>-<collection href="Genres"> <atom:title>Genres</atom:title> </collection>-<collection href="Titles"> <atom:title>Titles</atom:title> </collection>-<collection href="TitleAudioFormats"> <atom:title>TitleAudioFormats</atom:title> </collection>-<collection href="TitleAwards"> <atom:title>TitleAwards</atom:title> </collection>-<collection href="People"> <atom:title>People</atom:title> </collection>-<collection href="TitleScreenFormats"> <atom:title>TitleScreenFormats</atom:title> </collection>-<collection href="Languages"> <atom:title>Languages</atom:title> </collection> </workspace></service>

Page 10: Open Data Protocol (OData) Deep Dive

ENTITY DATA MODEL• Exposed on /$metadata• Describes Entity Model of Data Service• Entity Types• Complex Types• Association Types• EntityContainers

GET /odata.netflix.com/v2/Catalog/$metadata HTTP/1.1<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0"> <edmx:DataServices m:DataServiceVersion="1.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" Namespace="Netflix.Catalog.v2"> +<EntityType Name="Genre"> +<EntityType Name="Title" m:HasStream="true"> +<ComplexType Name="BoxArt"> +<Association Name="Genre_Titles"> +<EntityContainer Name="NetflixCatalog" m:IsDefaultEntityContainer="true"> </Schema> </edmx:DataServices></edmx:Edmx>

Page 11: Open Data Protocol (OData) Deep Dive

ENTITY TYPE• Named structures with keys• Support Inheritance• Properties• String, Integer, Boolean, DateTime, Spatial

datatypes • Collections, Complex Types• Relationship Properties

• May be marked as "Open"• May return "dynamic" properties not described in $metadata

<EntityType Name="Genre"> <Key> <PropertyRef Name="Name"/> </Key> <Property Name="Name" Type="Edm.String"/> <NavigationProperty Name="Titles" Relationship="Self.Genre_Titles" ToRole="Genre_Titles_Target" FromRole="Genre_Titles_Source"/></EntityType>

Page 12: Open Data Protocol (OData) Deep Dive

COMPLEX TYPE

• Named Structures w/o keys• Support Inheritance• Don't support relationships• Because they don't have an independent ID

<ComplexType Name="BoxArt"> <Property Name="SmallUrl" Type="Edm.String"/> <Property Name="MediumUrl" Type="Edm.String"/> <Property Name="LargeUrl" Type="Edm.String"/></ComplexType>

Page 13: Open Data Protocol (OData) Deep Dive

ASSOCIATIONS

• Define relationships (navigation paths) between Entities• Bi-directional• Specify Cardinality of each end• Can also impose integrity constraints

<Association Name="Genre_Titles"> <End Type="Self.Genre" Multiplicity="*" Role="Genre_Titles_Source"/> <End Type="Self.Title" Multiplicity="*" Role="Genre_Titles_Target"/></Association>

Page 14: Open Data Protocol (OData) Deep Dive

ENTITY CONTAINER

• Contains• EntitySets – collections of Entity Instances• AssociationSets – relationships between entities• FunctionImports – Actions/Functions exposed by

service

<EntityContainer Name="NetflixCatalog" m:IsDefaultEntityContainer="true"> <EntitySet Name="Genres" EntityType="Self.Genre"/> <EntitySet Name="Titles" EntityType="Self.Title"/> <AssociationSet Name="Genre_Titles" Association="Self.Genre_Titles"> <End Role="Genre_Titles_Source" EntitySet="Genres"/> <End Role="Genre_Titles_Target" EntitySet="Titles"/> </AssociationSet></EntityContainer>

Page 15: Open Data Protocol (OData) Deep Dive

DATA REQUESTS

Page 18: Open Data Protocol (OData) Deep Dive

OPERATORS

• Logical Operators• eq, ne, gt, ge, lt, le, and, or, not

• Mathematic Operators• add, sub, mult, div, mod

• Grouping Operator• ()

• NULL literal• null

Page 19: Open Data Protocol (OData) Deep Dive

BUILT-IN FUNCTIONS

• String Functions• substringof, endswith, startswith, length, indexof, substring,

tolower, toupper, trim, concat• DateTime Functions• year(), month(), day(), hour(), minute(), second()

• Math Functions• round(), floor(), ceiling()

• Type Functions• isof()

• Casting• Insert type in path

• Geo Functions• geo.length, geo.intersects, geo.distance

Page 21: Open Data Protocol (OData) Deep Dive

$TOP/$SKIP

• Enables Client-side paging through large result sets• GET /v2/Catalog/Titles?$top=10&$orderby=

AverageRating desc HTTP/1.1• GET /v2/Catalog/Titles?$top=10&$skip=10 &$orderby=

AverageRating desc HTTP/1.1

• If no $orderby, server guarantees stable ordering

Page 22: Open Data Protocol (OData) Deep Dive

$EXPAND

• Specify comma separated list of navigation property paths to include in response• GET /v2/Catalog/Titles?$expand=Cast,Awards HTTP/1.1

• Result are returned inline according to the appropriate format

Page 25: Open Data Protocol (OData) Deep Dive

$FORMAT

• Specify a particular format• "atom"

o application/atom+xml, o application/atomsvc+xml for service document

• "json"o application/json

• "xml"o application/xml

• Overrides content type specified in headers

Page 26: Open Data Protocol (OData) Deep Dive

SERVER DRIVEN PAGING

• Server controls the maximum number of records to return at a time• Each "page" of results includes a "next link"

for retrieving the next page of results• Pages can vary in size; some may be blank• i.e., return records as computed or across a

federation

Page 27: Open Data Protocol (OData) Deep Dive

DATA MODIFICATION

Page 28: Open Data Protocol (OData) Deep Dive

INSERT

• POST entity to the EntitySet collection• Returns inserted entity• Use PREFER header to request no content

returned• Media Resources have special rules

according to AtomPub:• POST media resource to the collection• Returns Media Link Entry• Update the Media Link Entry

Page 29: Open Data Protocol (OData) Deep Dive

UPDATE

• PUT to the edit-link to replace• Unspecified values are set to null or default

• PATCH to the edit-link to affect only specified values• Unspecified values are left unchanged

• Use PREFER header to request content returned• Use entity etag in if-match for concurrency

control• Obtained from header or payload

Page 30: Open Data Protocol (OData) Deep Dive

DELETE

• DELETE to the edit-link to delete• Use entity etag in if-match for concurrency

control• Obtained from header or payload

Page 31: Open Data Protocol (OData) Deep Dive

BATCH REQUESTS

• "Batch" multiple statements in a single multi-part mime request• Results for each statement returned in a

multi-part mime response• Multiple Data Modification statements may

be grouped in a single "ChangeSet"• ChangeSets are atomic• Reference the results of other statements in the

changeseto i.e., add a child to an added parent

• May have multiple ChangeSets per Batch

Page 32: Open Data Protocol (OData) Deep Dive

RELATIONSHIPS

Page 33: Open Data Protocol (OData) Deep Dive

REQUESTING RELATIONSHIP LINKS• Use $links to request the relationship links

for a particular navigation property• Results are returned as an array of URIso GET /v2/Catalog/Titles/Genres('Adventures')/$

links/Titles HTTP/1.1

Page 34: Open Data Protocol (OData) Deep Dive

CREATING LINKS TO NEW ENTITIES• Create a new Entity with a new related entity

by POSTing the entity with the related entity as inline content ("Deep Inserts")• Create a new entity related to an existing

entity by POSTing to the relationship collection of the existing entity

• POST /v2/Catalog/Titles/Genres('Adventures')/$links/Titles HTTP/1.1 <entry>…</entry>

Page 35: Open Data Protocol (OData) Deep Dive

CREATING LINKS TO EXISTING ENTITIES• Create a relationship between two existing

entities by POSTing the URL of the one entity to the appropriate $links collection of the other entityo POST /v2/Catalog/Titles/Genres('Adventures')/$links/Titles

HTTP/1.1 <uri>http://odata.netflix.com/v2/Catalog/Titles('13kbf')</uri>

Page 36: Open Data Protocol (OData) Deep Dive

DELETING LINKS

• Remove a relationship by sending a DELETE request to the $links collection specifying the url to removeo DELETE /v2/Catalog/Titles/Genres('Adventures')/$links/Titles

HTTP/1.1 <uri>http://odata.netflix.com/v2/Catalog/Titles('13kbf')</uri>

Page 37: Open Data Protocol (OData) Deep Dive

CONTENT TYPES (FORMATS)

Page 38: Open Data Protocol (OData) Deep Dive

ATOM FORMAT

• Multiple entities represented as a <feed>• Count optionally returned in <metadata:count> element• Next link returned as <link> element

• Each entity represented as an <entry>• <id> is unique id• <category> specifies type• Self, edit <link>s• <link> element for Relationships

o Inline content as child <metadata:inline> element containing feed or element• <link> element for editing media

• Properties nested in <metadata:properties> element• Individual properties namespace qualified with data namespace• For Media Resources, <content> has a src property to the media stream

o <metadata:properties> is a sibling of <content>• For non-Media Resources, <metadata:properties> is a child of <content>

• Functions/Actions returned as <metadata:function> and <metadata:action> elements

Page 39: Open Data Protocol (OData) Deep Dive

<?xml version="1.0" encoding="utf-8" ?><feed xml:base="http://odata.netflix.com/v2/Catalog/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom"> <title type="text">Genres</title> <id>http://odata.netflix.com/v2/Catalog/Genres/</id> <updated>2012-07-26T18:37:18Z</updated> <link rel="self" title="Genres" href="Genres" /> <m:count>326</m:count> <entry> <id>http://odata.netflix.com/v2/Catalog/Genres('Adventures')</id> <title type="text">Adventures</title> <updated>2012-07-26T19:08:35Z</updated> <author> <name/> </author> <link rel="edit" title="Genre" href="Genres('Adventures')" /> <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Titles" type="application/atom+xml;type=feed" title="Titles" href="Genres('Adventures')/Titles" /> <category term="Netflix.Catalog.v2.Genre" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" /> <content type="application/xml"> <m:properties> <d:Name>Adventures</d:Name> </m:properties> </content> </entry> <link rel="next" href="Genres/?$skiptoken='Adventures'" /></feed>

ATOM PAYLOAD - EXAMPLE

Page 40: Open Data Protocol (OData) Deep Dive

JSON VERBOSE FORMAT

• Results wrapped in a "d" wrapper• Multiple entities returned as JSON Array property named

"Result"o Optionally has __Count property for number of elements in query result

(across all pages)o Optionally has "__next" property for next link

• Each Entity has o A "__metadata" property containing:

– URI– Type– Media Link, edit-media link, content type, etag for media resources

o A "__deferred" property for each un-expanded relationship containing the URL for the related entity/collection

o Properties a Name/Value pairs• Each Complex Type has a "__metadata" property containing

the Type

Page 41: Open Data Protocol (OData) Deep Dive

JSON PAYLOAD - EXAMPLE{ "d" : { "results": [ { "__metadata": { "uri":"http://odata.netflix.com/Genres('Adventures')", "type": "Netflix.Catalog.v2.Genre" }, "Name": "Adventures", "Titles": { "__deferred": { "uri":"http://odata.netflix.com/Genres('Adventures')/Titles"} } } ], "__count": "326", "__next": " Genres/?$skiptoken='Adventures'" }}

Page 42: Open Data Protocol (OData) Deep Dive

NEW JSON ODATA FORMAT

• Effort to simplify JSON• More readable JSON format• Reduce size• Preserve OData-ness

o Still Hypermedia-driven• Uses Namespacing Mechanism

• Removes almost all metadata from payloads• Calculates values from conventions or templates in

metadata• 80-90% more efficient than Atom

• Future contribution to TC

Page 43: Open Data Protocol (OData) Deep Dive

NEW JSON PAYLOAD - EXAMPLE{ "odata.metadata":"http://odata.netflix.com/$metadata#Netflix/Genres", "count":"830", "value": [ { "Name": "Adventures", } ], "nextLink":" http://odata.netflix.com/Genres('Adventures')/Titles "}

Page 44: Open Data Protocol (OData) Deep Dive

EXTENSIBILITY

Page 45: Open Data Protocol (OData) Deep Dive

CUSTOM ACTIONS

• Side-effecting operations that may or may not return a value• May be exposed on instances (Hypermedia-

driven)• Use entity etag in if-match for concurrency

control• Obtained from header or payload

Page 46: Open Data Protocol (OData) Deep Dive

CUSTOM FUNCTIONS

• Extend query language• May be exposed on instances (Hypermedia-

driven)• Use entity etag in if-match for concurrency

control• Obtained from header or payload

Page 47: Open Data Protocol (OData) Deep Dive

VOCABULARIES

An OData Vocabulary defines a shareable set of Annotations that may be applied to metadata or instance data

• Extended Property Informationo Units of measuremento Read-only, read-write

• Ontologieso This entity represents the common concept of a person

• Validationo This integer property is between 10 and 20

• Display hintso Caption field, grouping, navigation

• Service Capabilitieso Query limitations, etc.

• Extensiono Analytics

Page 48: Open Data Protocol (OData) Deep Dive

ANNOTATIONS CONSIST OF:

• A Target: The construct against which the annotation is appliedo May be any Model Construct (type, property, etc.)

• A Term: The global name of the annotationo For example, org.odata.display.Title

• A Value: The value for the annotationo May be a static value, path, or expression

A Vocabulary is a set of terms in a common namespace

Page 49: Open Data Protocol (OData) Deep Dive

ANNOTATIONS MAY…

• Be defined in a common format• Machine readable (i.e., for validation)

• Be embedded in a model• To define extended metadata

• Be applied through an external annotation application file• Externally annotate existing services

• Be applied to Instance Data• Information that may vary per instance

Page 50: Open Data Protocol (OData) Deep Dive

TYPES OF ANNOTATIONS

• ValueTerm• A single annotation term applied to a type,

property, association, etc.• Complex TypeTerm• Generally used to describe an is-a relationship• Relationships may be modeled as properties of

individual or collections of other complex type terms

• Entity TypeTerm• Most prescriptive; define keys, relationships

Page 51: Open Data Protocol (OData) Deep Dive

UNANNOTATED ENTITY TYPE

<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="Sales">

<EntityContainer Name="Sales"> <EntitySet Name="Customer" EntityType="Sales.Customer"/></EntityContainer><EntityType Name="Customer"> <Key> <PropertyRef Name="CustomerID"/> </Key> <Property Name="CustomerID" Type="Edm.Integer" /> <Property Name="FirstName" Type="Edm.String" /> <Property Name="LastName" Type="Edm.String" /> <Property Name="Email" Type="Edm.String" /></EntityType>

</Schema>

Page 52: Open Data Protocol (OData) Deep Dive

VOCABULARY DEFINITIONS• “Person” vocabulary TypeTerm:

 

•  Display Vocabulary Value Terms

<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="myorg.schemas.person"><ComplexType Name="Person"> <Property Name="SSN" Type="Edm.String" /> <Property Name="GivenName" Type="Edm.String" /> <Property Name="FamilyName" Type="Edm.String" /> <Property Name="Gender" Type="Edm.String" /> <Property Name="Email" Type="Edm.String" /></ComplexType>

</Schema>

<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="org.odata.display"><ValueTerm Name="Caption" Type="Edm.String"/><ValueTerm Name="Description" Type="Edm.String"/><ValueTerm Name="ImageUrl" Type="Edm.String"/>

</Schema>

Page 53: Open Data Protocol (OData) Deep Dive

EXTERNAL ANNOTATION FILE

<edmx:Reference Url="http://www.odata.org/vocabularies/display/v1" /><edmx:Reference Url="http://www.myorg.com/schemas/person" /><edmx:Reference Url="http://www.myservice.com/sales.svc/$metadata" /><Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="Person"><Using Namespace="myorg.schemas.person" Alias="PersonVocabulary" /><Using Namespace="org.odata.display" Alias="Display" /><Using Namespace="Sales" Alias="Sales" /><Annotations Target="Sales.Customer"> <ValueAnnotation Term="Display.Caption" Path="CustomerID"/> <TypeAnnotation Term="PersonVocabulary.Person"> <PropertyValue Name="GivenName" Path="FirstName" /> <PropertyValue Name="FamilyName" Path="LastName" /> <PropertyValue Name="Email" Path="Email" /> </TypeAnnotation> </Annotations>

</Schema>

Page 54: Open Data Protocol (OData) Deep Dive

ANNOTATED METADATA<edmx:AnnotationsReference Url="http://odata.org/vocabularies/display/v1">  <Include TermNamespace ="myorg.schemas.person"/>  </edmx:AnnotationsReference><edmx:AnnotationsReference Url="http://odata.org/vocabularies/display/v1"> <Include TermNamespace ="org.odata.display"/></edmx:AnnotationsReference><Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="Sales">

<Using Namespace="myorg.schemas.person" Alias="PersonVocabulary" /><Using Namespace="org.odata.display" Alias="Display" /><EntityContainer Name="Sales"> <EntitySet Name="Customer" EntityType="Sales.Customer"/></EntityContainer><EntityType Name="Customer"> <Key> <PropertyRef Name="CustomerID"/> </Key> <Property Name="CustomerID" Type="Edm.Integer"> <ValueAnnotation Term="Display.Title" /> </Property> <Property Name="FirstName" Type="Edm.String" /> <Property Name="LastName" Type="Edm.String" /> <Property Name="Email" Type="Edm.String" /> <TypeAnnotation Term="PersonVocabulary.Person"> <PropertyValue Name="GivenName" Path="FirstName" /> <PropertyValue Name="FamilyName" Path="LastName" /> <PropertyValue Name="Email" Path="Email" /> </TypeAnnotation>

</EntityType></Schema>

Page 55: Open Data Protocol (OData) Deep Dive

INSTANCE ANNOTATIONS

{ "odata.json.metadata": "http://myservice.com/sales.svc/$metadata#Sales.Customer", "results" : { “CustomerID" : 123, "FirstName" : "John", "LastName" : "Public", "Email" : "[email protected]" , "@CustomerID" : { odata.org.display.readonly : true } }}

Page 56: Open Data Protocol (OData) Deep Dive

ANNOTATION/METADATA REFERENCING• AnnotationReference• Specifies a separate document that annotates this

model• Constrain to individual namespaces, qualifiers

through "Include"• Reference• Brings a separate model "into scope" for use

within this model

Page 57: Open Data Protocol (OData) Deep Dive

SUMMARY

• OData =REST o Entities, Entity Sets as URI addressable Resourceso Hypermedia Driveno CRUD = POST, GET, PUT/PATCH, DELETE

+ Data Modelo Entity Relational Model

+ Common Conventionso Query Syntax, Server Driven Paging, …

+ Common Formatso Atom, JSON

+ Extensibilityo Custom Functions, Actions, Shared Annotations

Page 58: Open Data Protocol (OData) Deep Dive
Page 59: Open Data Protocol (OData) Deep Dive

BACKUP

Page 60: Open Data Protocol (OData) Deep Dive

 {  "d": {    "results": [    {        "__metadata": {          "uri": "http://services.odata.org/OData/OData.svc/Products(0)",           "type": "ODataDemo.Product"        },      "ID": 0,      "Name": "Bread",      "Description": "Whole grain bread",      "ReleaseDate": "\/Date(694224000000)\/",      "DiscontinuedDate": null,      "Rating": 4,      "Price": "2.5",       "Category": {        "__deferred": {          "uri": "http://services.odata.org/OData/OData.svc/Products(0)/Category"        }      },       "Supplier": {        "__deferred": {          "uri": "http://services.odata.org/OData/OData.svc/Products(0)/Supplier"        }      }    },     {      "__metadata": {        "uri": "http://services.odata.org/OData/OData.svc/Products(1)",         "type": "ODataDemo.Product"      },      "ID": 1,      "Name": "Milk",      "Description": "Low fat milk",      "ReleaseDate": "\/Date(812505600000)\/",      "DiscontinuedDate": null,      "Rating": 3,      "Price": "3.5",       "Category": {        "__deferred": {          "uri": "http://services.odata.org/OData/OData.svc/Products(1)/Category"        }      },       "Supplier": {        "__deferred": {          "uri": "http://services.odata.org/OData/OData.svc/Products(1)/Supplier"        }      }    }],    "__count": 9  }}

{  "odata.json.metadata": "http://services.odata.org/OData/OData.svc/$metadata#ODataDemo.DemoService.Products",  "results": [  {    "ID": 0,    "Name": "Bread",    "Description": "Whole grain bread",    "ReleaseDate": "\/Date(694224000000)\/",    "DiscontinuedDate": null,    "Rating": 4,    "Price": "2.5"  },  {    "ID": 1,    "Name": "Milk",    "Description": "Low fat milk",    "ReleaseDate": "\/Date(812505600000)\/",    "DiscontinuedDate": null,    "Rating": 3,    "Price": "3.5"  }],  "__count": 9}

OData.svc/Products?$top=2&$inlinecount=allpages&$format=json

Page 61: Open Data Protocol (OData) Deep Dive

QUERY

• $filter• Basic predicates, built-in functions

• $sort• Properties, expressions

• $select• Narrow the set of fields returned

• $top/$skip• Client-side paging

• $expand • Include related entities

• $count/$inlinecount• Include count of entities

• Server Driven Paging

Page 62: Open Data Protocol (OData) Deep Dive

ENTITY DATA MODEL• Entity Types

• Named structures with keys• Support Inheritance• May be Open

• Properties• String, Integer, Boolean, DateTime,

Spatial datatypes • Collections, Complex Types• Relationship Properties

• Complex Types• Named Structures w/o keys• Can’t have relationships

to ComplexTypes• Associations

• Expose navigation paths• EntityContainer

• Contains EntitySets, AssociationSets, FunctionImports

<EntityType Name="Genre"> <Key> <PropertyRef Name="Name"/> </Key> <Property Name="Name" Type="Edm.String"/> <NavigationProperty Name="Titles" Relationship="Self.Genre_Titles" ToRole="Genre_Titles_Target" FromRole="Genre_Titles_Source"/></EntityType>

<ComplexType Name="BoxArt"> <Property Name="SmallUrl" Type="Edm.String"/> <Property Name="MediumUrl" Type="Edm.String"/> <Property Name="LargeUrl" Type="Edm.String"/></ComplexType><Association Name="Genre_Titles"> <End Type="Self.Genre" Multiplicity="*" Role="Genre_Titles_Source"/> <End Type="Self.Title" Multiplicity="*" Role="Genre_Titles_Target"/></Association><EntityContainer Name="NetflixCatalog"> <EntitySet Name="Genres" EntityType="Self.Genre"/> <EntitySet Name="Titles" EntityType="Self.Title"/> <AssociationSet Name="Genre_Titles" Association="Self.Genre_Titles"> <End Role="Genre_Titles_Source" EntitySet="Genres"/> <End Role="Genre_Titles_Target" EntitySet="Titles"/> </AssociationSet></EntityContainer>