OData-protokolvejledning

1. Introduktion

I denne vejledning udforsker vi OData, en standardprotokol, der giver nem adgang til datasæt ved hjælp af en RESTFul API.

2. Hvad er? OData?

OData er en OASIS- og ISO / IEC-standard til adgang til data ved hjælp af en RESTful API. Som sådan tillader det en forbruger at opdage og navigere gennem datasæt ved hjælp af standard HTTP-opkald.

For eksempel kan vi få adgang til en af ​​de offentligt tilgængelige OData-tjenester med en simpel krølle one-liner:

krølle -s //services.odata.org/V2/Northwind/Northwind.svc/Regions Regions //services.odata.org/V2/Northwind/Northwind.svc/Regions ... resten af ​​xml-svar udeladt

I skrivende stund har OData-protokollen sin 4. version - 4.01 for at være mere præcis. OData V4 nåede OASIS-standardniveauet i 2014, men det har en længere historie. Vi kan spore sine rødder til et Microsoft-projekt kaldet Astoria, der blev omdøbt til ADO.Net Data Services i 2007. Den originale blogindgang, der annoncerer dette projekt, er stadig tilgængelig på Microsofts OData-blog.

At have en standardbaseret protokol for at få adgang til datasættet giver nogle fordele i forhold til standard API'er som JDBC eller ODBC. Som slutbrugerniveauforbruger kan vi bruge populære værktøjer som Excel til at hente data fra enhver kompatibel udbyder. Programmering fremmes også af et stort antal tilgængelige REST-klientbiblioteker.

Som udbydere har vedtagelse af OData også fordele: Når vi først har oprettet en kompatibel tjeneste, kan vi fokusere på at levere værdifulde datasæt, som slutbrugere kan forbruge ved hjælp af de værktøjer, de vælger. Da det er en HTTP-baseret protokol, kan vi også udnytte aspekter såsom sikkerhedsmekanismer, overvågning og logning.

Disse egenskaber gjorde OData til et populært valg af offentlige agenturer, når de implementerer offentlige datatjenester, som vi kan kontrollere ved at se på denne mappe.

3. OData-koncepter

Kernen i OData-protokollen er begrebet en enhedsdatamodel - eller kort sagt EDM. EDM beskriver data eksponeret af en OData-udbyder gennem et metadatadokument indeholdende et antal meta-enheder:

  • Enhedstype og dens egenskaber (f.eks. Person, Kunde, Bestilleosv.) og nøgler
  • Forhold mellem enheder
  • Komplekse typer, der bruges til at beskrive strukturerede typer indlejret i enheder (f.eks. En adressetype, der er en del af en Kunde type)
  • Enhedssæt, som samler enheder af en given type

Specifikationen pålægger, at dette metadatadokument skal være tilgængeligt på standardplaceringen $ metadata ved rod-URL'en, der bruges til at få adgang til tjenesten. For eksempel, hvis vi har en OData-tjeneste tilgængelig på //eksempel.org/odata.svc/, så vil metadata-dokumentet være tilgængeligt på //eksempel.org/odata.svc/$metadata.

Det returnerede dokument indeholder en masse XML, der beskriver de skemaer, der understøttes af denne server:

   ... skemaelementer udeladt 

Lad os nedbryde dette dokument i dets hovedafsnit.

Elementet på øverste niveau, kan kun have et barn, den element.Den vigtige ting at bemærke her er navneområdet URI, da det giver os mulighed for at identificere hvilken OData-version serveren bruger. I dette tilfælde angiver navneområdet, at vi har en OData V2-server, der bruger Microsofts identifikatorer.

EN DataServices element kan have en eller flere Skema elementer, der hver beskriver et tilgængeligt datasæt. Da en komplet beskrivelse af de tilgængelige elementer i a Skema er uden for denne artikels anvendelsesområde, vil vi fokusere på de vigtigste: Enhedstyper, foreninger, og EntitySets.

3.1. EntityType Element

Dette element definerer de tilgængelige egenskaber for en given enhed, inklusive dens primære nøgle. Det kan også indeholde oplysninger om forhold til andre skematyper og ved at se på et eksempel - a CarMaker - vi kan se, at det ikke er meget forskelligt fra beskrivelser, der findes i andre ORM-teknologier, såsom JPA:

Her, vores CarMaker har kun to egenskaber - Id og Navn - og en tilknytning til en anden EntityType. Det Nøgle sub-element definerer enhedens primære nøgle til at være dens Id ejendom og hver Ejendom element indeholder data om en enheds ejendom, såsom dens navn, type eller ugyldighed.

EN NavigationEjendom er en særlig form for ejendom, der beskriver et "adgangspunkt" til en relateret enhed.

3.2. Forening Element

En Forening element beskriver en sammenhæng mellem to enheder, som inkluderer mangfoldigheden i hver ende og eventuelt en begrænsning af henvisningens integritet:

Her, den Forening element definerer et en-til-mange forhold mellem en CarModel og CarMaker enheder, hvor førstnævnte fungerer som den afhængige part.

3.3. EntitySet Element

Det sidste skemakoncept, vi vil udforske, er EntitySet element, der repræsenterer en samling af enheder af en given type. Selvom det er let at tænke dem som analoge med en tabel - og i mange tilfælde er de netop det - en bedre analogi er den af ​​en visning. Årsagen til det er, at vi kan have flere EntitySet elementer til det samme EntityTypehvor hver repræsenterer en anden delmængde af de tilgængelige data.

Det EntityContainer element, som er et skemaelement på øverste niveau, grupperer alle tilgængelige EntitySets:

I vores enkle eksempel har vi kun to EntitySets, men vi kunne også tilføje yderligere visninger, f.eks ForeignCarMakers eller HistoricCarMakers.

4. OData-URL'er og -metoder

For at få adgang til data eksponeret af en OData-tjeneste bruger vi de almindelige HTTP-verber:

  • GET returnerer en eller flere enheder
  • POST tilføjer en ny enhed til en eksisterende Enhedssæt
  • PUT erstatter en given enhed
  • PATCH erstatter specifikke egenskaber for en given enhed
  • SLET fjerner en given enhed

Alle disse operationer kræver en ressourcesti at handle på. Ressourcestien kan definere et enhedsæt, en enhed eller endda en ejendom inden for en enhed.

Lad os se på et eksempel på en URL, der bruges til at få adgang til vores tidligere OData-tjeneste:

//eksempel.org/odata/CarMakers 

Den første del af denne URL, startende med protokollen op til odata / stisegment, er kendt som service rod-URL og er den samme for alle ressourcestier i denne tjeneste. Da serviceroden altid er den samme, erstatter vi den i de følgende URL-prøver med en ellipsis (“…”).

Bilproducenteri dette tilfælde henviser til en af ​​de erklærede EntitySets i servicemetadataene. Vi kan bruge en almindelig browser til at få adgang til denne URL, som derefter skal returnere et dokument, der indeholder alle eksisterende enheder af denne type:

  // localhost: 8080 / odata / CarMakers CarMakers 2019-04-06T17: 51: 33.588-03: 00 // localhost: 8080 / odata / CarMakers (1L) CarMakers 2019-04-06T17: 51: 33.589-03: 00 1 Special Motors ... andre poster udeladt 

Det returnerede dokument indeholder en indgang element for hver CarMaker eksempel.

Lad os se nærmere på, hvilke oplysninger vi har til rådighed for os:

  • id: et link til denne specifikke enhed
  • titel / forfatter / opdateret: metadata om denne post
  • link elementer: Links, der bruges til at pege på en ressource, der bruges til at redigere enheden (rel = ”rediger”) eller til beslægtede enheder. I dette tilfælde har vi et link, der fører os til sæt af CarModel enheder tilknyttet netop dette CarMaker.
  • indhold: egenskabsværdier på CarModel enhed

Et vigtigt punkt at bemærke her er brugen af ​​nøgleværdipar til at identificere en bestemt enhed i et enhedsæt. I vores eksempel er nøglen numerisk, så en ressourcesti som CarMaker (1L) henviser til enheden med en primær nøgleværdi lig med 1 - "L”Her betegner bare en lang værdi og kunne udelades.

5. Forespørgselsmuligheder

Vi kan videresende forespørgselsmuligheder til en ressource-URL for at ændre et antal aspekter af de returnerede data, f.eks. For at begrænse størrelsen på det returnerede sæt eller dets rækkefølge. OData-specifikationen definerer et rigt sæt muligheder, men her fokuserer vi på de mest almindelige.

Forespørgselsmuligheder kan som hovedregel kombineres med hinanden, hvilket gør det muligt for klienter nemt at implementere almindelige funktioner såsom personsøgning, filtrering og ordning af resultatlister.

5.1. $ top og $ spring over

Vi kan navigere gennem et stort datasæt ved hjælp af $ top en $ spring over forespørgsel muligheder:

... / CarMakers? $ Top = 10 & $ skip = 10 

$ top fortæller tjenesten, at vi kun vil have de første 10 poster af Bilproducenter enhedssæt. EN $ spring, som anvendes før $ top, fortæller serveren at springe de første 10 poster over.

Det er normalt nyttigt at kende størrelsen på en given Enhedssæt og til dette formål kan vi bruge $ tæller underressource:

... / CarMakers / $ count 

Denne ressource producerer en tekst / almindelig dokument, der indeholder størrelsen på det tilsvarende sæt. Her skal vi være opmærksomme på den specifikke OData-version, der understøttes af en udbyder. Mens OData V2 understøtter $ tæller som en underressource fra en samling tillader V4, at den kan bruges som en forespørgselsparameter. I dette tilfælde, $ tæller er en boolsk, så vi skal ændre URL'en i overensstemmelse hermed:

... / CarMakers? $ Count = true 

5.2. $ filter

Vi bruger $ filter forespørgsel mulighed til begrænse de returnerede enheder fra en given Enhedssæt til de matchende givne kriterier. Værdien for $ filter er et logisk udtryk, der understøtter grundlæggende operatorer, gruppering og en række nyttige funktioner. Lad os for eksempel oprette en forespørgsel, der returnerer alle CarMaker tilfælde hvor dens Navn attribut starter med bogstavet 'B':

... / CarMakers? $ Filter = startswith (Navn, 'B') 

Lad os nu kombinere et par logiske operatorer til at søge efter CarModels af et bestemt År og Maker:

... / CarModels? $ Filter = Year eq 2008 and CarMakerDetails / Name eq 'BWM' 

Her har vi brugt ligestillingsoperatøren ækv for at specificere værdier for egenskaberne. Vi kan også se, hvordan man bruger egenskaber fra en relateret enhed i udtrykket.

5.3. $ udvid

Som standard returnerer en OData-forespørgsel ikke data for relaterede enheder, som normalt er OK. Vi kan bruge $ udvid forespørgselsmulighed for at anmode om, at data fra en given relateret enhed inkluderes integreret med hovedindholdet.

Brug vores eksempeldomæne til at opbygge en URL, der returnerer data fra en given model og dets producent og dermed undgå en ekstra rundtur til serveren:

... / CarModels (1L)? $ Expand = CarMakerDetails 

Det returnerede dokument inkluderer nu CarMaker data som en del af den relaterede enhed:

  //eksempel.org/odata/CarModels(1L) CarModels 2019-04-07T11: 33: 38.467-03: 00 //example.org/odata/CarMakers(1L) CarMakers 2019-04-07T11: 33: 38.492-03 : 00 1 Special Motors 1 1 Muze SM001 2018 

5.4. $ vælg

Vi bruger $ select-forespørgsel til at informere OData-tjenesten om, at den kun skal returnere værdierne for de givne egenskaber. Dette er nyttigt i scenarier, hvor vores enheder har et stort antal ejendomme, men vi er kun interesserede i nogle af dem.

Lad os bruge denne mulighed i en forespørgsel, der kun returnerer Navn og Sku ejendomme:

... / CarModels (1L)? $ Select = Navn, SKU 

Det resulterende dokument har nu kun de ønskede egenskaber:

... xml udeladt Muze SM001 ... xml udeladt

Vi kan også se, at selv relaterede enheder blev udeladt. For at inkludere dem skal vi medtage navnet på forholdet i $ vælg mulighed.

5.5. $ ordre

Det $ ordre option fungerer stort set som dets SQL-modstykke. Vi bruger det til at specificere den rækkefølge, som vi ønsker, at serveren skal returnere et givet sæt enheder. I sin enklere form er dens værdi kun en liste over ejendomsnavne fra den valgte enhed, der eventuelt informerer ordreretningen:

... / CarModels? $ OrderBy = Navn asc, Sku desc 

Denne forespørgsel vil resultere i en liste over CarModels ordnet efter deres navne og SKU'er i henholdsvis stigende og faldende retning.

En vigtig detalje her er tilfældet, der bruges med retningsdelen af ​​en given egenskab: mens specifikationen kræver, at serveren skal understøtte enhver kombination af store og små bogstaver til nøgleordene asc og beskrivelse, det også mandater, at klienten kun skal bruge små bogstaver.

5.6. $ format

Denne indstilling definerer det datarepræsentationsformat, som serveren skal bruge, som har forrang over ethvert HTTP-indholdsforhandlingsoverskrift, såsom Acceptere. Dens værdi skal være en fuld MIME-type eller en format-specifik kort form.

For eksempel, vi kan bruge json som en forkortelse for ansøgning / json:

... / CarModels? $ Format = json 

Denne URL beder vores service om at returnere data ved hjælp af JSON-format i stedet for XML, som vi har set før. Når denne indstilling ikke er til stede, bruger serveren værdien af Acceptere header, hvis det findes. Når ingen af ​​disse er tilgængelige, kan serveren vælge enhver repræsentation - normalt XML eller JSON.

Med hensyn til JSON specifikt er det grundlæggende skamløs. Imidlertid definerer OData 4.01 også et JSON-skema for metadataendepunkter. Det betyder, at vi nu kan skrive klienter, der kan slippe af med XML-behandling, hvis de vælger at gøre det.

6. Konklusion

I denne korte introduktion til OData har vi dækket dens grundlæggende semantik, og hvordan man udfører enkel datasættnavigation. Vores opfølgningsartikel fortsætter, hvor vi forlod og går direkte ind i Olingo-biblioteket. Vi ser derefter, hvordan vi implementerer eksempler på tjenester ved hjælp af dette bibliotek.

Kodeeksempler er som altid tilgængelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found