Transcript
Page 1: Building RESTfull Data Services with WebAPI
Page 2: Building RESTfull Data Services with WebAPI

Building RESTfull Data Services with WebAPIGert Drapers (#DataDude)

Principle Software Design Engineer

Page 3: Building RESTfull Data Services with WebAPI

Agenda

•Overview

•OData Core Libraries

•Web API

•Web API Demo

Page 4: Building RESTfull Data Services with WebAPI

Overview

Page 5: Building RESTfull Data Services with WebAPI

OData Value Proposition

•Problem Statement: • There is no consistent data interoperability protocol for addressing and

manipulating enterprise data across various devices and platforms

•Value Proposition:• OData enables consistent REST-based data access from a variety of back

ends including relational databases, file systems, content management systems, and traditional Web sites

• OData builds on widely-accepted standards like HTTP, JSON, AtomPub, and URIs to address and access data

Page 6: Building RESTfull Data Services with WebAPI

What OData Is and Is Not?

•What OData Is:• Easy, consistent data access via HTTP endpoints• REST-based data operations: CRUD, Filtering, Sorting, Paging, Custom

Operations, Delta, etc.• Service centric data definition, operation and annotation• Schematized and schema-less data sets• Broadly accepted JSON/ATOM format on the wire

•What OData Is Not: • Not to replace native or direct data access interface, e.g. ODBC/TDS for SQL• Not to replace highly specialized BI technologies like XMLA

Page 7: Building RESTfull Data Services with WebAPI

OData Status

• OData v4 to be standardized in Feb. in OASIS• http://docs.oasis-open.org/odata/new-in-odata/v4.0/cn01/new-in-odata-v4.0-

cn01.html

• ODL 6.2• http://blogs.msdn.com/b/odatateam/archive/2014/04/14/odl-6-2-release-

announcement.aspx

• Web API OData 6.1• http://blogs.msdn.com/b/odatateam/archive/2014/03/21/odata-6-1-and-odata-

client-6-1-are-now-shipped.aspx

• WCF Data Services moved to OSS• http://blogs.msdn.com/b/odatateam/archive/2014/03/27/future-direction-of-wcf-

data-services.aspx

http://odata.org/

Page 8: Building RESTfull Data Services with WebAPI

OData Core Libraries

Page 9: Building RESTfull Data Services with WebAPI

Technology BasicsClient Server

OData Service

OData Protocol Library

OData Data

Model Library

Data Source

Technology .NET

OData Data Model Library Microsoft.odata.edm.dll

OData Protocol Library Microsoft.odata.core.dll

OData Service WCF Data Service/ Web API/ User’s own service

OData Client Library Microsoft.odata.client.dll

Code Generator T4 / item template

OData Protocol Library

OData Data

Model Library

OData Client Library

OData Protocol Library

OData Data

Model Library

Page 10: Building RESTfull Data Services with WebAPI

How to build client to consume OData

Business Logic

Dev OData Service

Metadata request

Use Code Generatror to generate client class

Client Application

Account account = TestClientContext.Accounts.Where(account => account.AccountID == 110).Single();account.Country=”US”;TestClientContext.UpdateObject(account);TestClientContext.SaveChanges();

Code Files(Account.cs/TestClientContext.cs)

Microsoft.odata.client.dll

The client dll will generate the request based on the property change on the Account objectGet http://localhost:8080/OData/Accounts(110)Patch http://localhost:8080/OData/Accounts(110)

Page 11: Building RESTfull Data Services with WebAPI

What’s in Microsoft.OData.Client.dll

•Deserialize/Serialize OData payload• Using API provided by Microsoft.OData.Core.dll

•Request Generator/LINQ to URL

•Entity Tracker

•Batch support

Page 12: Building RESTfull Data Services with WebAPI

OData Data Model Library

•OData is based on the Entity Data Model (EDM):• EDM presents information in a way which is familiar to

many developers dealing with data today making it easy for them to understand and use.•Data provider can use OData Data Model Library to create

the EDM model of the data they want to expose. The client can consume the data based on the EDM model that exposed by service and figure out the relationship between entities.

Page 13: Building RESTfull Data Services with WebAPI

EDM ExampleEntity Container

Entity set(Categories)

CategoryCategoryId Product

Entity set(Products)

ProductProductId Description

Navigation property binding

Page 14: Building RESTfull Data Services with WebAPI

EDM Example – Cont.• <?xml version="1.0" encoding="utf-8"?>

<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices>

<Schema Namespace="Microsoft.Test.OData.Services.ODataWCFService" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="Category">

<Key><PropertyRef Name="CategoryId" />

</Key><Property Name="CategoryId" Type="Edm.String" Nullable="false" /><Property Name="Name" Type="Edm.String" Nullable="false" /><NavigationProperty Name="Product" Type="Microsoft.Test.OData.Services.ODataWCFService.Product" Nullable="false" />

</EntityType><EntityType Name="Product">

<Key><PropertyRef Name="ProductId" />

</Key><Property Name="ProductId" Type="Edm.String" Nullable="false" /><Property Name="Name" Type="Edm.String" Nullable="false" /><Property Name="Desciption" Type="Edm.String" Nullable="false" />

</EntityType><EntityContainer Name="ServiceContainer">

<EntitySet Name="Categories" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Category"><NavigationPropertyBinding Path="Product" Target="Products" />

</EntitySet><EntitySet Name="Products" EntityType="Microsoft.Test.OData.Services.ODataWCFService.Product"></EntitySet>

</EntityContainer></Schema>

</edmx:DataServices></edmx:Edmx>

Page 15: Building RESTfull Data Services with WebAPI

EDM Example – Cont.

•Category Entity:• http://localhost/odata/Categories(1)• Product under this category• http://localhost/odata/Categories(1)/Product

• Through navigation binding defined in the Categories and the navigation property defined in the Category, target entity set Products can be found

• Entity product can be located in entity set Products

Page 16: Building RESTfull Data Services with WebAPI

OData Protocol Library• Deserialize/Serialize payload

• JSON• Full metadata level

– {– "@odata.context":"http://localhost:50671/ODataService.svc/OData/$metadata#Products/$entity",– "@odata.id":"http://localhost:50671/ODataService.svc/OData/Products(5)",– "@odata.editLink":"http://localhost:50671/ODataService.svc/OData/Products(5)",– "ProductID":5,– "Name":"Cheetos",– "Description":"Cheese curl"– }

• Minimal metadata level– Writer only writes the necessary metadata– Reader will auto complete the metadata during reading– {– "@odata.context":"http://localhost:50671/ODataService.svc/OData/$metadata#Products/$entity",– "ProductID":5,– "Name":"Cheetos",– "Description":"Cheese curl"– }

• No metadata level– Data only– {– "ProductID":5,– "Name":"Cheetos",– "Description":"Cheese curl"– }

• ATOM

Page 17: Building RESTfull Data Services with WebAPI

OData Protocol Library

• Targeting the target resource based on the URI• $top=n: Returns only the first n entities in an entity set (or in Atom terms, the

first n entries in a feed)• $skip=n: Skips the first n entities in an entity set. Using this option lets a client

retrieve a series of distinct pages on subsequent requests• $format: Determines whether data should be returned in JSON or the XML-

based Atom/AtomPub format• $orderby=: Orders results, in ascending or descending order, by the value of

one or more properties in those results• $filter=: Returns only entities that match the specified expression• $select=: Returns only the specified properties in an entity• $expand=: Returns the navigation property in an entity

URI Parser

Page 18: Building RESTfull Data Services with WebAPI

OData Protocol Library – Cont.

• http://services.odata.org/V3/Northwind/Northwind.svc/Order_Details?$top=5&$select=OrderID,ProductID&$skip=1&$filter=OrderID gt 10248

• Parsed result of request URI as an ODataUri object • TopCount• SkipCount• SelectExpandClause• List<SelectedItem>

– PathSelectionItem» Path=OrderID

– PathSelectionItem» Path=ProductID

• FilterClause• FilterExpression

Page 19: Building RESTfull Data Services with WebAPI

OData Web API

Page 20: Building RESTfull Data Services with WebAPI

WebApi.OData: Overview

•An OData service library

•Build upon a lightweight http stack

•Be part of ASP.NET RESTful framework

•Selective query ability

•Another option to build OData service

Page 21: Building RESTfull Data Services with WebAPI

Simple way to build OData Service

•No need to know the details of OData Protocol

•POCO (Plain Old CLR Object) model

•ODataConventionModelBuilder: 3 lines of codevar builder = new ODataConventionModelBuilder();

builder.EntitySet<Product>("Products");IEdmModel model = builder.GetEdmModel();

•ODataController: VS2013 scaffolding

Page 22: Building RESTfull Data Services with WebAPI

Web API OData Architecture Diagram

Message Handler

Controller Selection

ODataController

Action

Action Filter

MapODataRoute*GetEdmModelModel builderEdm Lib

Spatial Lib

Formatter

OData LibSerialize

DeserializeQuery

Entity Framework

DbContextDbSet

Action Filter

Formatter Model Binder QueryOption

Action Selection

Type system

HttpRequestMessage

HttpResponseMessage

Page 23: Building RESTfull Data Services with WebAPI

Components

• Model builder• ODataModelBuilder• ODataConventionModelBuilder (a 3 lines of code approach)

• Query• ODL Semantic AST -> LINQ Expression (IQueryable) -> LINQ to * (Entities, Objects…)

• Routing• Conventional• Attribute route

• Formatter• Serializer: CLR type / typeless -> OData*Value• Deserializer: OData*Value -> CLR type / typeless

Page 24: Building RESTfull Data Services with WebAPI

Routing Examples

// Metadata routes to support $metadata and code generation in the // WCF Data Service client.configuration.Routes.MapHttpRoute(

ODataRouteNames.Metadata, "$metadata", new { Controller = "ODataMetadata", Action = "GetMetadata" }

); configuration.Routes.MapHttpRoute(

ODataRouteNames.ServiceDocument, "", new { Controller = "ODataMetadata", Action = "GetServiceDocument" }

);

Page 25: Building RESTfull Data Services with WebAPI

Routing Examples…

// Relationship routes (notice the parameters is {type}Id not id, // this avoids colliding with GetById(id)). // This code handles requests like ~/ProductFamilies(1)/Products configuration.Routes.MapHttpRoute(

ODataRouteNames.PropertyNavigation, "{controller}({parentId})/{navigationProperty}");

// Route for manipulating links, the code allows people to create and // delete relationships between entities configuration.Routes.MapHttpRoute(

ODataRouteNames.Link, "{controller}({id})/$links/{navigationProperty}");

Page 26: Building RESTfull Data Services with WebAPI

Routing Examples…

// Routes for urls both producing and handling URLs// like: ~/Product(1), ~/Products() and ~/Products configuration.Routes.MapHttpRoute(

ODataRouteNames.GetById, "{controller}({id})");

configuration.Routes.MapHttpRoute(ODataRouteNames.DefaultWithParentheses, "{controller}()");

configuration.Routes.MapHttpRoute(ODataRouteNames.Default, "{controller}");

Page 27: Building RESTfull Data Services with WebAPI

Model Builder

• ODataConventionModelBuilder• Use reflection and conventions to generate an Edm model

• Reflection• Type• PropertyInfo• MethodInfo

• Conventions• AttributeConvention• AttributeEdmTypeConvention: [DataContract]• AttributeEdmPropertyConvention:

• [Key]• [DataMember]• [IgnoreDataMember]• [Required]• [ConcurrencyCheck]…

Page 28: Building RESTfull Data Services with WebAPI

ODataModelBuilder

• Take full controlvar builder = new ODataModelBuilder();var products = builder.EntitySet<Product>("Products");var product = products.EntityType;product.HasKey(p => p.ID);product.Property(p => p.Name);var rate = product.Action("Rate");rate.Parameter<int>("Rating");rate.Returns<double>();

• EntitySetConfiguration

• EntityTypeConfiguration

• PropertyConfiguration

• ProcedureConfiguration

• ParameterConfiguration

Page 29: Building RESTfull Data Services with WebAPI

Query

• /Products/?$filter=Name eq ‘abc’• One key differentiator than other Web API implementations

• QueryableAttribute[Queryable]public IQueryable<Product> GetProducts(){

return db.Products;}

• => ODataQueryOptionspublic IEnumerable<Product> GetProducts(ODataQueryOptions options){

return options.ApplyTo(db.Products) as IEnumerable<Product>;}

• FilterQueryOption -> FilterBinder:• Convert OData AST FilterClause’s QueryNode to Linq Expression

Page 30: Building RESTfull Data Services with WebAPI

Routing

• IODataRoutingConvention• string SelectController(ODataPath odataPath, HttpRequestMessage request);• string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string,

HttpActionDescriptor> actionMap);

• Convention based route:• EntitySetRoutingConvention• EntityRoutingConvention• ActionRoutingConvention• FunctionRoutingConvention• NavigationRoutingConvention• PropertyRoutingConvention

• Attribute based route:• AttributeRoutingConvention• ODataRouteAttribute

• MapODataRoute

Page 31: Building RESTfull Data Services with WebAPI

Formatter

• Why does webapi.odata need to handle serialization and deserialization?• ODL handles OData object model to Payload• Web API handles POCO to OData OM

• The hook:[ODataFormatting]public abstract class ODataController : ApiController

• ODataFormattingAttribute• Inserts the ODataMediaTypeFormatters into the HttpControllerSettings.Formatters collection.• Attaches the request to the OData formatter instance.

• ODataMediaTypeFormatter.Create()• ODataSerializerProvider / ODataDeserializerProvider• OData*Serializer / OData*Deserializer

Page 32: Building RESTfull Data Services with WebAPI

DemoBuild an OData Web API application

Page 33: Building RESTfull Data Services with WebAPI

Laat ons weten wat u vindt van deze sessie! Vul de evaluatie in via www.techdaysapp.nl en maak kans op een van de 20 prijzen*. Prijswinnaars worden bekend gemaakt via Twitter (#TechDaysNL). Gebruik hiervoor de code op uw badge.

Let us know how you feel about this session! Give your feedback via www.techdaysapp.nl and possibly win one of the 20 prices*. Winners will be announced via Twitter (#TechDaysNL). Use your personal code on your badge.

* Over de uitslag kan niet worden gecorrespondeerd, prijzen zijn voorbeelden – All results are final, prices are examples

Page 34: Building RESTfull Data Services with WebAPI

Top Related