OPEN DATA PROTOCOL ODATA DEEP DIVE A common

  • Slides: 62
Download presentation
OPEN DATA PROTOCOL (ODATA) DEEP DIVE A common, open, RESTful Web protocol for querying

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 o Entities modeled as URI-addressable Resources o Relationships modeled

ODATA = REST • Resource-oriented o Entities modeled as URI-addressable Resources o Relationships modeled as links (URIs) o CRUD = POST, GET, PUT/PATCH, DELETE • Hypermedia-driven o 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

USE OF HTTP • HTTP Methods • GET, POST, PUT/PATCH, DELETE • HTTP Headers

USE OF HTTP • HTTP Methods • GET, POST, PUT/PATCH, DELETE • HTTP Headers • Content Negotiation o Accept, Accept-Charset, Accept-Encoding, Accept-Language o Content-Type, Content-Length, Content-Encoding, Content-Language • Concurrency o Etags, If-Match, If-None-Match • Etc… • HTTP Result Codes • 2 xx Success Codes • 3 xx Redirection • 4 xx Client Error Messages

ODATA FEATURE AREAS • • Versioning Service Metadata Data Requests Data Modification Relationships Content

ODATA FEATURE AREAS • • Versioning Service Metadata Data Requests Data Modification Relationships Content Types Extensibility

VERSIONING

VERSIONING

PROTOCOL VERSIONING • Data. Service. Version header • Describes the protocol version according to

PROTOCOL VERSIONING • Data. Service. Version header • Describes the protocol version according to which the request/response should be interpreted • Max. Data. Service. Version Request Header • The maximum protocol version that the client can accept • Min. Data. Service. Version Request Header • The minimum protocol version the client can accept -Clients SHOULD specify a Max. Data. Service -Services return a response formatted according to the latest protocol version the service supports that is less than Max. Data. Service. Version but at least Min. Data. Service. Version

SCHEMA VERSIONING • When a data model or other breaking change is made to

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/v 1/Catalog • odata. netflix. com/v 2/Catalog

SERVICE METADATA

SERVICE METADATA

SERVICE DOCUMENT • Root of service exposes a “Service Document” • Describes collections of

SERVICE DOCUMENT • Root of service exposes a “Service Document” • Describes collections of Entities GET /odata. netflix. com/v 2/Catalog HTTP/1. 1 <service xmlns="http: //www. w 3. org/2007/app" xmlns: app="http: //www. w 3. org/2007/app" xmlns: atom="http: //www. w 3. org/2005/Atom" xml: base="http: //odata. netflix. com/v 2/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="Title. Audio. Formats"> <atom: title>Title. Audio. Formats</atom: title> </collection>-<collection href="Title. Awards"> <atom: title>Title. Awards</atom: title> </collection>-<collection href="People"> <atom: title>People</atom: title> </collection>-<collection href="Title. Screen. Formats"> <atom: title>Title. Screen. Formats</atom: title> </collection>-<collection href="Languages"> <atom: title>Languages</atom: title> </collection> </workspace> </service>

ENTITY DATA MODEL • Exposed on /$metadata • Describes Entity Model of Data Service

ENTITY DATA MODEL • Exposed on /$metadata • Describes Entity Model of Data Service • • Entity Types Complex Types Association Types Entity. Containers GET /odata. netflix. com/v 2/Catalog/$metadata HTTP/1. 1 <edmx: Edmx xmlns: edmx="http: //schemas. microsoft. com/ado/2007/06/edmx" Version="1. 0"> <edmx: Data. Services m: Data. Service. Version="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. v 2"> +<Entity. Type Name="Genre"> +<Entity. Type Name="Title" m: Has. Stream="true"> +<Complex. Type Name="Box. Art"> +<Association Name="Genre_Titles"> +<Entity. Container Name="Netflix. Catalog" m: Is. Default. Entity. Container="true"> </Schema> </edmx: Data. Services> </edmx: Edmx>

ENTITY TYPE • Named structures with keys • Support Inheritance • Properties • String,

ENTITY TYPE • Named structures with keys • Support Inheritance • Properties • String, Integer, Boolean, Date. Time, Spatial datatypes • Collections, Complex Types • Relationship Properties • May be marked as "Open" • May return "dynamic" properties not described in $metadata <Entity. Type Name="Genre"> <Key> <Property. Ref Name="Name"/> </Key> <Property Name="Name" Type="Edm. String"/> <Navigation. Property Name="Titles" Relationship="Self. Genre_Titles" To. Role="Genre_Titles_Target" From. Role="Genre_Titles_Source"/> </Entity. Type>

COMPLEX TYPE • Named Structures w/o keys • Support Inheritance • Don't support relationships

COMPLEX TYPE • Named Structures w/o keys • Support Inheritance • Don't support relationships • Because they don't have an independent ID <Complex. Type Name="Box. Art"> <Property Name="Small. Url" Type="Edm. String"/> <Property Name="Medium. Url" Type="Edm. String"/> <Property Name="Large. Url" Type="Edm. String"/> </Complex. Type>

ASSOCIATIONS • Define relationships (navigation paths) between Entities • Bi-directional • Specify Cardinality of

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>

ENTITY CONTAINER • Contains • Entity. Sets – collections of Entity Instances • Association.

ENTITY CONTAINER • Contains • Entity. Sets – collections of Entity Instances • Association. Sets – relationships between entities • Function. Imports – Actions/Functions exposed by service <Entity. Container Name="Netflix. Catalog" m: Is. Default. Entity. Container="true"> <Entity. Set Name="Genres" Entity. Type="Self. Genre"/> <Entity. Set Name="Titles" Entity. Type="Self. Title"/> <Association. Set Name="Genre_Titles" Association="Self. Genre_Titles"> <End Role="Genre_Titles_Source" Entity. Set="Genres"/> <End Role="Genre_Titles_Target" Entity. Set="Titles"/> </Association. Set> </Entity. Container>

DATA REQUESTS

DATA REQUESTS

QUERYING DATA • Querying a Set • GET /v 2/Catalog/Genres HTTP/1. 1 • Requesting

QUERYING DATA • Querying a Set • GET /v 2/Catalog/Genres HTTP/1. 1 • Requesting an Individual Entity by ID • GET /v 2/Catalog/Genres('Adventures') HTTP/1. 1 • Requesting an Individual Property • GET /v 2/Catalog/Genres('Adventures')/Name HTTP/1. 1 • Requesting an Individual Property Raw Value • GET /v 2/Catalog/Genres('Adventures')/Name/$value HTTP/1. 1

$FILTER • Basic predicates, built-in functions • GET /v 2/Catalog/Titles? $filter=Name eq 'The Sting'

$FILTER • Basic predicates, built-in functions • GET /v 2/Catalog/Titles? $filter=Name eq 'The Sting' HTTP/1. 1 • Filter on Properties of a derived type • Only returns entities of that type that match the predicate • GET /v 2/Catalog/Awards? $filter=Netflix. Academy. Award/Category HTTP/1. 1 • Query based on collection Membership using Any/All • GET /v 2/Catalog/Titles? $filter=Genres/Any(g: g/Name eq 'Adventure') HTTP/1. 1

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

OPERATORS • Logical Operators • eq, ne, gt, ge, lt, le, and, or, not • Mathematic Operators • add, sub, mult, div, mod • Grouping Operator • () • NULL literal • null

BUILT-IN FUNCTIONS • String Functions • substringof, endswith, startswith, length, indexof, substring, tolower, toupper,

BUILT-IN FUNCTIONS • String Functions • substringof, endswith, startswith, length, indexof, substring, tolower, toupper, trim, concat • Date. Time 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

$ORDERBY • Comma separated list of properties, expressions • GET /v 2/Catalog/Titles? $orderby=Average. Rating,

$ORDERBY • Comma separated list of properties, expressions • GET /v 2/Catalog/Titles? $orderby=Average. Rating, Release. Year HTTP/1. 1 • Can specify asc (default) or desc • GET /v 2/Catalog/Titles? $orderby=Average. Rating desc HTTP/1. 1

$TOP/$SKIP • Enables Client-side paging through large result sets • GET /v 2/Catalog/Titles? $top=10&$orderby=Average.

$TOP/$SKIP • Enables Client-side paging through large result sets • GET /v 2/Catalog/Titles? $top=10&$orderby=Average. Rating desc HTTP/1. 1 • GET /v 2/Catalog/Titles? $top=10&$skip=10 &$orderby=Average. Rating desc HTTP/1. 1 • If no $orderby, server guarantees stable ordering

$EXPAND • Specify comma separated list of navigation property paths to include in response

$EXPAND • Specify comma separated list of navigation property paths to include in response • GET /v 2/Catalog/Titles? $expand=Cast, Awards HTTP/1. 1 • Result are returned inline according to the appropriate format

$SELECT • Narrow the set of fields returned • GET /v 2/Catalog/Titles? $select=Name, Synopsis,

$SELECT • Narrow the set of fields returned • GET /v 2/Catalog/Titles? $select=Name, Synopsis, Rating HTTP/1. 1 • Related properties must be specified in $expand • GET /v 2/Catalog/Titles? $select=Name, Cast/Name&$expand=Cast HTTP/1. 1 • Can include all properties using * • Does not include navigation properties • GET /v 2/Catalog/Titles? $select=* HTTP/1. 1

$COUNT/$INLINECOUNT • Get just the count • Can include additional query operators • GET

$COUNT/$INLINECOUNT • Get just the count • Can include additional query operators • GET /v 2/Catalog/Titles/$count HTTP/1. 1 • Include the count with the results • $inlinecount ignores $top/$skip but includes $filter • GET /v 2/Catalog/Titles? $inlinecount=allpages&$top=10 HTTP/1. 1

$FORMAT • Specify a particular format • "atom" o application/atom+xml, o application/atomsvc+xml for service

$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

SERVER DRIVEN PAGING • Server controls the maximum number of records to return at

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

DATA MODIFICATION

DATA MODIFICATION

INSERT • POST entity to the Entity. Set collection • Returns inserted entity •

INSERT • POST entity to the Entity. Set collection • Returns inserted entity • Use PREFER header to request no content returned • Media Resources have special rules according to Atom. Pub: • POST media resource to the collection • Returns Media Link Entry • Update the Media Link Entry

UPDATE • PUT to the edit-link to replace • Unspecified values are set to

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

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

DELETE • DELETE to the edit-link to delete • Use entity etag in if-match for concurrency control • Obtained from header or payload

BATCH REQUESTS • "Batch" multiple statements in a single multi-part mime request • Results

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 "Change. Set" • Change. Sets are atomic • Reference the results of other statements in the changeset o i. e. , add a child to an added parent • May have multiple Change. Sets per Batch

RELATIONSHIPS

RELATIONSHIPS

REQUESTING RELATIONSHIP LINKS • Use $links to request the relationship links for a particular

REQUESTING RELATIONSHIP LINKS • Use $links to request the relationship links for a particular navigation property • Results are returned as an array of URIs o GET /v 2/Catalog/Titles/Genres('Adventures')/$links/Titles HTTP/1. 1

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

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 /v 2/Catalog/Titles/Genres('Adventures')/$links/Titles HTTP/1. 1 <entry>…</entry>

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

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 entity o POST /v 2/Catalog/Titles/Genres('Adventures')/$links/Titles HTTP/1. 1 <uri>http: //odata. netflix. com/v 2/Catalog/Titles('13 kbf')</uri>

DELETING LINKS • Remove a relationship by sending a DELETE request to the $links

DELETING LINKS • Remove a relationship by sending a DELETE request to the $links collection specifying the url to remove o DELETE /v 2/Catalog/Titles/Genres('Adventures')/$links/Titles HTTP/1. 1 <uri>http: //odata. netflix. com/v 2/Catalog/Titles('13 kbf')</uri>

CONTENT TYPES (FORMATS)

CONTENT TYPES (FORMATS)

ATOM FORMAT • Multiple entities represented as a <feed> • • Count optionally returned

ATOM FORMAT • Multiple entities represented as a <feed> • • Count optionally returned in <metadata: count> element Next link returned as <link> element • • <id> is unique id <category> specifies type Self, edit <link>s <link> element for Relationships • Each entity represented as an <entry> • 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

ATOM PAYLOAD - EXAMPLE <? xml version="1. 0" encoding="utf-8" ? > <feed xml: base="http:

ATOM PAYLOAD - EXAMPLE <? xml version="1. 0" encoding="utf-8" ? > <feed xml: base="http: //odata. netflix. com/v 2/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. w 3. org/2005/Atom"> <title type="text">Genres</title> <id>http: //odata. netflix. com/v 2/Catalog/Genres/ </id> <updated>2012 -07 -26 T 18: 37: 18 Z</updated> <link rel="self" title="Genres" href="Genres" /> <m: count>326</m: count> <entry> <id>http: //odata. netflix. com/v 2/Catalog/Genres('Adventures') </id> <title type="text">Adventures</title> <updated>2012 -07 -26 T 19: 08: 35 Z</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. v 2. 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>

JSON VERBOSE FORMAT • Results wrapped in a "d" wrapper • Multiple entities returned

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

JSON PAYLOAD - EXAMPLE { "d" : { "results": [ { "__metadata": { "uri":

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

NEW JSON ODATA FORMAT • Effort to simplify JSON • More readable JSON format

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

NEW JSON PAYLOAD - EXAMPLE { "odata. metadata": "http: //odata. netflix. com/$metadata#Netflix/Genres", "count": "830",

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

EXTENSIBILITY

EXTENSIBILITY

CUSTOM ACTIONS • Side-effecting operations that may or may not return a value •

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

CUSTOM FUNCTIONS • Extend query language • May be exposed on instances (Hypermedia-driven) •

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

VOCABULARIES An OData Vocabulary defines a shareable set of Annotations that may be applied

VOCABULARIES An OData Vocabulary defines a shareable set of Annotations that may be applied to metadata or instance data • Extended Property Information o Units of measurement o Read-only, read-write • Ontologies o This entity represents the common concept of a person • Validation o This integer property is between 10 and 20 • Display hints o Caption field, grouping, navigation • Service Capabilities o Query limitations, etc. • Extension o Analytics

ANNOTATIONS CONSIST OF: • A Target: The construct against which the annotation is applied

ANNOTATIONS CONSIST OF: • A Target: The construct against which the annotation is applied o May be any Model Construct (type, property, etc. ) • A Term: The global name of the annotation o For example, org. odata. display. Title • A Value: The value for the annotation o May be a static value, path, or expression A Vocabulary is a set of terms in a common namespace

ANNOTATIONS MAY… • Be defined in a common format • Machine readable (i. e.

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

TYPES OF ANNOTATIONS • Value. Term • A single annotation term applied to a

TYPES OF ANNOTATIONS • Value. Term • A single annotation term applied to a type, property, association, etc. • Complex Type. Term • Generally used to describe an is-a relationship • Relationships may be modeled as properties of individual or collections of other complex type terms • Entity Type. Term • Most prescriptive; define keys, relationships

UNANNOTATED ENTITY TYPE <Schema xmlns="http: //schemas. microsoft. com/ado/2008/09/edm" Namespace="Sales"> <Entity. Container Name="Sales"> <Entity. Set

UNANNOTATED ENTITY TYPE <Schema xmlns="http: //schemas. microsoft. com/ado/2008/09/edm" Namespace="Sales"> <Entity. Container Name="Sales"> <Entity. Set Name="Customer" Entity. Type="Sales. Customer"/> </Entity. Container> <Entity. Type Name="Customer"> <Key> <Property. Ref Name="Customer. ID"/> </Key> <Property Name="Customer. ID" Type="Edm. Integer" /> <Property Name="First. Name" Type="Edm. String" /> <Property Name="Last. Name" Type="Edm. String" /> <Property Name="Email" Type="Edm. String" /> </Entity. Type> </Schema>

VOCABULARY DEFINITIONS • “Person” vocabulary Type. Term: <Schema xmlns="http: //schemas. microsoft. com/ado/2008/09/edm" Namespace="myorg. schemas.

VOCABULARY DEFINITIONS • “Person” vocabulary Type. Term: <Schema xmlns="http: //schemas. microsoft. com/ado/2008/09/edm" Namespace="myorg. schemas. person"> <Complex. Type Name="Person"> <Property Name="SSN" Type="Edm. String" /> <Property Name="Given. Name" Type="Edm. String" /> <Property Name="Family. Name" Type="Edm. String" /> <Property Name="Gender" Type="Edm. String" /> <Property Name="Email" Type="Edm. String" /> </Complex. Type> </Schema> • Display Vocabulary Value Terms <Schema xmlns="http: //schemas. microsoft. com/ado/2008/09/edm" Namespace="org. odata. display"> <Value. Term Name="Caption" Type="Edm. String"/> <Value. Term Name="Description" Type="Edm. String"/> <Value. Term Name="Image. Url" Type="Edm. String"/> </Schema>

EXTERNAL ANNOTATION FILE <edmx: Reference Url="http: //www. odata. org/vocabularies/display/v 1" /> <edmx: Reference Url="http:

EXTERNAL ANNOTATION FILE <edmx: Reference Url="http: //www. odata. org/vocabularies/display/v 1" /> <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="Person. Vocabulary" /> <Using Namespace="org. odata. display" Alias="Display" /> <Using Namespace="Sales" Alias="Sales" /> <Annotations Target="Sales. Customer"> <Value. Annotation Term="Display. Caption" Path="Customer. ID"/> <Type. Annotation Term="Person. Vocabulary. Person"> <Property. Value Name="Given. Name" Path="First. Name" /> <Property. Value Name="Family. Name" Path="Last. Name" /> <Property. Value Name="Email" Path="Email" /> </Type. Annotation> </Annotations> </Schema>

ANNOTATED METADATA <edmx: Annotations. Reference Url="http: //odata. org/vocabularies/display/v 1 "> <Include Term. Namespace ="myorg.

ANNOTATED METADATA <edmx: Annotations. Reference Url="http: //odata. org/vocabularies/display/v 1 "> <Include Term. Namespace ="myorg. schemas. person"/> </edmx: Annotations. Reference> <edmx: Annotations. Reference Url="http: //odata. org/vocabularies/display/v 1 "> <Include Term. Namespace ="org. odata. display"/> </edmx: Annotations. Reference> <Schema xmlns="http: //schemas. microsoft. com/ado/2008/09/edm " Namespace="Sales"> <Using Namespace="myorg. schemas. person" Alias="Person. Vocabulary" /> <Using Namespace="org. odata. display" Alias="Display" /> <Entity. Container Name="Sales"> <Entity. Set Name="Customer" Entity. Type="Sales. Customer"/> </Entity. Container> <Entity. Type Name="Customer"> <Key> <Property. Ref Name="Customer. ID"/> </Key> <Property Name="Customer. ID" Type="Edm. Integer"> <Value. Annotation Term="Display. Title" /> </Property> <Property Name="First. Name" Type="Edm. String" /> <Property Name="Last. Name" Type="Edm. String" /> <Property Name="Email" Type="Edm. String" /> <Type. Annotation Term="Person. Vocabulary. Person"> <Property. Value Name="Given. Name" Path="First. Name" /> <Property. Value Name="Family. Name" Path="Last. Name" /> <Property. Value Name="Email" Path="Email" /> </Type. Annotation> </Entity. Type> </Schema>

INSTANCE ANNOTATIONS { "odata. json. metadata": "http: //myservice. com/sales. svc/$metadata#Sales. Customer", "results" : {

INSTANCE ANNOTATIONS { "odata. json. metadata": "http: //myservice. com/sales. svc/$metadata#Sales. Customer", "results" : { “Customer. ID" : 123, "First. Name" : "John", "Last. Name" : "Public", "Email" : "John@public. com" , "@Customer. ID" : { odata. org. display. readonly : true } } }

ANNOTATION/METADATA REFERENCING • Annotation. Reference • Specifies a separate document that annotates this model

ANNOTATION/METADATA REFERENCING • Annotation. Reference • 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

SUMMARY • OData = REST o Entities, Entity Sets as URI addressable Resources o

SUMMARY • OData = REST o Entities, Entity Sets as URI addressable Resources o Hypermedia Driven o CRUD = POST, GET, PUT/PATCH, DELETE + Data Model o Entity Relational Model + Common Conventions o Query Syntax, Server Driven Paging, … + Common Formats o Atom, JSON + Extensibility o Custom Functions, Actions, Shared Annotations

BACKUP

BACKUP

OData. svc/Products? $top=2&$inlinecount=allpages&$format=json { "d": { "results": [ { "__metadata": { "uri": "http: //services.

OData. svc/Products? $top=2&$inlinecount=allpages&$format=json { "d": { "results": [ { "__metadata": { "uri": "http: //services. odata. org/OData. svc/Products(0)", "type": "OData. Demo. Product" }, "ID": 0, "Name": "Bread", "Description": "Whole grain bread", "Release. Date": "/Date(694224000000)/", "Discontinued. Date": null, "Rating": 4, "Price": "2. 5", "Category": { "__deferred": { "uri": "http: //services. odata. org/OData. svc/Products(0)/Category" } }, "Supplier": { "__deferred": { "uri": "http: //services. odata. org/OData. svc/Products(0)/Supplier" } } }, { "__metadata": { "uri": "http: //services. odata. org/OData. svc/Products(1)", "type": "OData. Demo. Product" }, "ID": 1, "Name": "Milk", "Description": "Low fat milk", "Release. Date": "/Date(812505600000)/", "Discontinued. Date": null, "Rating": 3, "Price": "3. 5", "Category": { "__deferred": { "uri": "http: //services. odata. org/OData. svc/Products(1)/Category" } }, "Supplier": { "__deferred": { "uri": "http: //services. odata. org/OData. svc/Products(1)/Supplier" } } }], "__count": 9 } } { "odata. json. metadata": "http: //services. odata. org/OData. svc/$metadata#OData. Demo. Service. Products", "results": [ { "ID": 0, "Name": "Bread", "Description": "Whole grain bread", "Release. Date": "/Date(694224000000)/", "Discontinued. Date": null, "Rating": 4, "Price": "2. 5" }, { "ID": 1, "Name": "Milk", "Description": "Low fat milk", "Release. Date": "/Date(812505600000)/", "Discontinued. Date": null, "Rating": 3, "Price": "3. 5" }], "__count": 9 }

QUERY • $filter • Basic predicates, built-in functions • $sort • Properties, expressions •

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

ENTITY DATA MODEL • Entity Types • Named structures with keys • Support Inheritance

ENTITY DATA MODEL • Entity Types • Named structures with keys • Support Inheritance • May be Open <Entity. Type Name="Genre"> <Key> <Property. Ref Name="Name"/> </Key> <Property Name="Name" Type="Edm. String"/> <Navigation. Property Name="Titles" Relationship="Self. Genre_Titles" To. Role="Genre_Titles_Target" From. Role="Genre_Titles_Source"/> </Entity. Type> <Complex. Type Name="Box. Art"> <Property Name="Small. Url" Type="Edm. String"/> <Property Name="Medium. Url" Type="Edm. String"/> <Property Name="Large. Url" Type="Edm. String"/> </Complex. Type> <Association Name="Genre_Titles"> <End Type="Self. Genre" Multiplicity="*" Role="Genre_Titles_Source"/> <End Type="Self. Title" Multiplicity="*" Role="Genre_Titles_Target"/> </Association> <Entity. Container Name="Netflix. Catalog"> <Entity. Set Name="Genres" Entity. Type="Self. Genre"/> <Entity. Set Name="Titles" Entity. Type="Self. Title"/> <Association. Set Name="Genre_Titles" Association="Self. Genre_Titles"> <End Role="Genre_Titles_Source" Entity. Set="Genres"/> <End Role="Genre_Titles_Target" Entity. Set="Titles"/> </Association. Set> </Entity. Container> • Properties • String, Integer, Boolean, Date. Time, Spatial datatypes • Collections, Complex Types • Relationship Properties • Complex Types • Named Structures w/o keys • Can’t have relationships to Complex. Types • Associations • Expose navigation paths • Entity. Container • Contains Entity. Sets, Association. Sets, Function. Imports