Open Data Protocol gör det enklare bygga REST-baserade tjänster

Open Data Protocol, eller OData som det ofta förkortas, var en av de nyheter som presenterades på PDC-konferensen i november. OData är ett öppet protokoll för att hantera frågor och uppdateringar mot datakällor som exponeras med hjälp av REST-baserade tjänster. Med öppet menas att det är publicerad under Microsoft's Open Specification Promise och alltså är helt fritt att använda för implementeringar i andra teknikstackar än Microsofts egna (vilket också har skett – mer om det längre ner).

REST, som står för ‘Representational State Transfer’, är som bekant en arkitekturstil som beskriver hur du bygger tjänster som exponeras via URI:er, där du arbetar med  HTTP-protokollets GET, PUT, POST och DELETE-verb för att hämta, skapa, uppdatera och radera data. REST är ett mönster som blivit mer och mer populärt som ett alternativ till SOAP i tjänstebaserade arkitekturer.

Några av anledningarna till att REST har haft såna framgångar tror jag är:

  • REST-baserade tjänster är i grunden interoperabla vilket är lämpligt när man har en många olika typer av klienter.
  • Tjänsterna går att skala med befintliga lastbalanserare och cache-servrar eftersom du använder HTTP-protokollets grundmetoder.
  • Resurser går att upptäcka och borra sig ner i genom sin URI – d.v.s. adressen i sig är en beskrivning av resurserna som du kommer att hämta eller påverka – vilket gör det enkelt att förstå, testa och felsöka tjänsterna.
  • REST är tillståndslöst i sin natur vilket tvingar in dig i ett asynkront tänk – vilket i sin tur gör det enklare att bygga skalbara tjänster.

Ett problem har varit att det har saknats bra plattformsoberoende angreppsätt för att arbeta riktigt effektivt med REST-baserade tjänster. T.ex. så har det inte funnits något standardiserat sätt att beskriva datastrukturerna som tjänsterna returnerar, vilket har gjort det svårt att automatgenerera proxy-klienter samt ge Intellisense-stöd på klientsidan. Det har också saknats ett enhetligt sätt att ange filter-utryck och andra urvalsvillkor i tjänsteanropen. Ett exempel kan vara att du t.ex. vill kunna stega dig igenom ett resultatset i en datamängd.

Open Data Protocol, som i sin tur bygger på HTTP- och AtomPub-protokollen, tillför funktionalitet för att baka in metadata som beskriver den datastruktur som en REST-baserad tjänst erbjuder. Protokollet beskriver också en syntax för hur du begär att tjänsten ska filtrera det data som den returnerar. OData är egentligen inget nytt – implementeringar har tidigare funnits under benämningarna “Astoria” Protocol och ADO.NET Data Services Protocol. OData är ett sätt att samla dessa i ett enhetligt protokoll och göra det öppet tillgängligt.

Nedan är ett exempel på hur kommunikation med hjälp av OData kan se ut. Ett GET-anrop mot min Northwind-tjänst kan returnera en Atom-feed som visar vilka entiteter som min tjänst exponerar:

GET /Northwind.svc/ HTTP/1.1

 <?xml version="1.0" encoding="utf-8" standalone="yes" ?> 
<service xml:base=https://localhost:1308/Northwind.svc/ 
  xmlns:atom=https://www.w3.org/2005/Atom 
  xmlns:app="https://www.w3.org/2007/app" xmlns="https://www.w3.org/2007/app">
<workspace>
<atom:title>Default</atom:title> 
<collection href="Categories">
<atom:title>Categories</atom:title> 
</collection>
<collection href="Products">
<atom:title>Products</atom:title> 
</collection>
</workspace>
</service>

Genom att ange Products och ange ett id som parameter i URL:en kan jag få ut en enskild produkt:

GET /Northwind.svc/Products(1) HTTP/1.1

 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base="https://127.0.0.1:1308/Northwind.svc/" xmlns:d=https://schemas.microsoft.com/ado/2007/08/dataservices 
  xmlns:m="https://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="https://www.w3.org/2005/Atom">
  <id>https://127.0.0.1:1308/Northwind.svc/Products(1)</id>
  <title type="text"></title>
  <updated>2010-01-18T21:52:38Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="Product" href="Products(1)" />
  <link rel="https://schemas.microsoft.com/ado/2007/08/dataservices/related/Category" type="application/atom+xml;type=entry" 
  title="Category" href="Products(1)/Category" />
  <category term="NorthwindModel.Product" scheme="https://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:ProductID m:type="Edm.Int32">1</d:ProductID>
      <d:ProductName>Chai</d:ProductName>
      <d:QuantityPerUnit>10 boxes x 20 bags</d:QuantityPerUnit>
      <d:UnitPrice m:type="Edm.Decimal">18.0000</d:UnitPrice>
      <d:UnitsInStock m:type="Edm.Int16">39</d:UnitsInStock>
      <d:UnitsOnOrder m:type="Edm.Int16">0</d:UnitsOnOrder>
      <d:ReorderLevel m:type="Edm.Int16">10</d:ReorderLevel>
      <d:Discontinued m:type="Edm.Boolean">false</d:Discontinued>
    </m:properties>
  </content>
</entry>

Men genom utökningen av AtomPub-protokollet och namnrymden ‘https://schemas.microsoft.com/ado/2007/08/dataservices/metadata’ (Data Services Metadata Namespace) så beskrivs också vilka datatyper som den aktuella entiteten innehåller. Till exempel att egenskapen ‘Discontinued’ är en ‘Edm.Boolean’ (Edm står för Entity Data Model). På så sätt kan en klient använda sig av metadata för t.ex. proxy-generering, typ-check och Intellisense.

Så här kan en filtrering och sortering se ut med OData-syntax:

GET /Northwind.svc/Products/?Category=Beverages&$orderby=ProductName&$top=2&$filter=Discontinued eq false HTTP/1.1

Ovanstående uttryck skulle ge de två första produkterna som har Category ‘Beverages’ där egenskapen Discontiued är satt till ‘false’ –  sorterat på ProductName.

En sak som jag tycker är intressant med Open Data Protocol är att det redan finns ett antal icke-Microsoft implementeringar av protokollet – t.ex. finns det en Java-implementation, stöd inbyggt i WebSphere och en PHP-implementation. Bygger du REST-baserade tjänster i .NET och vill dra nytta av OData så kan du med fördel använda WCF Data Services (finns både för .NET 4 och 3.5 SP1). Men det finns också inbyggt stöd för OData i många produkter och plattformar som släppts eller är på väg att släppas – t.ex. Sharepoint 2010 och PowerPivot.

Här finns en bra FAQ om OData – själva protokollet hittar du på www.odata.org – missa inte heller Pablo Castros briljanta session om WCF Data Services och Odata från PDC-konferensen.