Del via


TripPin del 2 – Dataconnector til en REST-tjeneste

Dette selvstudium i flere dele dækker oprettelsen af en ny datakildeudvidelse til Power Query. Selvstudiet er beregnet til at blive udført sekventielt – hver lektion bygger på den connector, der blev oprettet i tidligere lektioner, og føjer trinvist nye funktioner til din connector.

I denne lektion skal du:

  • Opret en basisfunktion, der kalder til en REST-API ved hjælp af Web.Contents
  • Få mere at vide om, hvordan du angiver anmodningsheadere og behandler et JSON-svar
  • Brug Power BI Desktop til at omarrangere svaret til et brugervenligt format

I denne lektion konverteres den OData-baserede connector for TripPin-tjenesten (oprettet i den forrige lektion) til en connector, der ligner noget, du ville oprette for en HVILKEN som helst RESTful-API. OData er en RESTful API, men en med et fast sæt konventioner. Fordelen ved OData er, at den indeholder et skema, en protokol til datahentning og et standardforespørgselssprog. Hvis du fjerner brugen af OData.Feed , kræver det, at vi selv bygger disse funktioner ind i connectoren.

Resumé af OData-connectoren

Før du fjerner OData-funktionerne fra din connector, kan vi hurtigt gennemgå, hvad den i øjeblikket gør (hovedsageligt i baggrunden) for at hente data fra tjenesten.

Åbn TripPin-udvidelsesprojektet fra del 1 i Visual Studio Code. Åbn forespørgselsfilen, og indsæt følgende forespørgsel:

TripPin.Feed("https://services.odata.org/v4/TripPinService/Me")

Åbn Fiddler, og evaluer derefter den aktuelle Power Query-fil i Visual Studio Code.

I Fiddler er der tre anmodninger til serveren:

Fiddler OData-anmodninger.

  • /Me– den faktiske URL-adresse, du anmoder om.
  • /$metadata– et kald, der automatisk foretages af funktionen OData.Feed for at bestemme skemaet og skrive oplysninger om svaret.
  • /Me/BestFriend– et af de felter, der (ivrigt) blev trukket, da du oplistede /Me-singletonen. I dette tilfælde resulterede opkaldet i en 204 No Content status.

M evaluering er for det meste doven. I de fleste tilfælde hentes/hentes dataværdier kun, når der er behov for dem. Der er scenarier (f.eks. /Me/BestFriend-sagen), hvor en værdi trækkes med spænding. Dette sker ofte, når typeoplysninger er nødvendige for et medlem, og programmet ikke har anden måde at bestemme typen på end at hente værdien og undersøge den. At gøre tingene dovne (dvs. undgå ivrige træk) er et af de vigtigste aspekter for at gøre en M-connector effektiv.

Bemærk de anmodningsheadere, der blev sendt sammen med anmodningerne og JSON-formatet for svaret på /Me-anmodningen.

{
  "@odata.context": "https://services.odata.org/v4/TripPinService/$metadata#Me",
  "UserName": "aprilcline",
  "FirstName": "April",
  "LastName": "Cline",
  "MiddleName": null,
  "Gender": "Female",
  "Age": null,
  "Emails": [ "April@example.com", "April@contoso.com" ],
  "FavoriteFeature": "Feature1",
  "Features": [ ],
  "AddressInfo": [
    {
      "Address": "P.O. Box 555",
      "City": {
        "Name": "Lander",
        "CountryRegion": "United States",
        "Region": "WY"
      }
    }
  ],
  "HomeAddress": null
}

Når forespørgslen er færdig med at evaluere, skal resultatvinduet for PQTest vise postværdien for me-singletonen.

OData-resultater.

Hvis du sammenligner felterne i outputvinduet med de felter, der returneres i det rå JSON-svar, kan du se en uoverensstemmelse. Forespørgselsresultatet indeholder andre felter (Friends, Trips, GetFriendsTrips), der ikke vises nogen steder i JSON-svaret. Funktionen OData.Feed føjede automatisk disse felter til posten baseret på det skema, der blev returneret af $metadata. Dette er et godt eksempel på, hvordan en connector kan øge og/eller omformatere svaret fra tjenesten for at give en bedre brugeroplevelse.

Oprettelse af en grundlæggende REST-connector

Du skal nu føje en ny eksporteret funktion til din connector, der kalder Web.Contents.

Hvis du vil kunne foretage vellykkede webanmodninger til OData-tjenesten, skal du dog angive nogle OData-standardheadere. Det gør du ved at definere et fælles sæt overskrifter som en ny variabel i din connector:

DefaultRequestHeaders = [
    #"Accept" = "application/json;odata.metadata=minimal",  // column name and values only
    #"OData-MaxVersion" = "4.0"                             // we only support v4
];

Du ændrer implementeringen af din TripPin.Feed funktion, så den i stedet for at bruge OData.Feedbruger Web.Contents til at oprette en webanmodning og fortolker resultatet som et JSON-dokument.

TripPinImpl = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source)
    in
        json;

Husk at bygge din connector nu, hvor du har foretaget ændringer af connectorfilen. Derefter kan du evaluere forespørgselsfilen (TripPin.query.pq). Resultatet af posten /Me ligner nu den rå JSON, du så i Fiddler-anmodningen.

Hvis du ser Fiddler, når du kører den nye funktion, vil du også bemærke, at evalueringen nu foretager en enkelt webanmodning i stedet for tre. Tillykke – du har opnået en stigning i ydeevnen på 300 %! Du har nu mistet alle type- og skemaoplysninger, men der er endnu ingen grund til at fokusere på den del.

Opdater din forespørgsel for at få adgang til nogle af TripPin-enheder/-tabeller, f.eks.:

  • https://services.odata.org/v4/TripPinService/Airlines
  • https://services.odata.org/v4/TripPinService/Airports
  • https://services.odata.org/v4/TripPinService/Me/Trips

Du vil bemærke, at de stier, der brugte til at returnere pænt formaterede tabeller, nu returnerer et felt på øverste niveau med et integreret [Liste]. Du skal foretage nogle transformationer af resultatet for at gøre det brugbart for slutbrugerforbrugsscenarier.

Vis resultater.

Oprettelse af transformationer i Power Query

Selvom det er muligt at oprette dine M-transformationer manuelt, foretrækker de fleste at bruge Power Query til at forme deres data. Du skal åbne din udvidelse i Power BI Desktop og bruge den til at designe forespørgsler for at gøre outputtet til et mere brugervenligt format. Byg din løsning igen, kopiér den nye filtypenavnsfil til mappen Brugerdefinerede data Forbind orer, og relancer Power BI Desktop igen.

Start en ny tom forespørgsel, og indsæt følgende på formellinjen:

= TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines")

Sørg for at medtage =-tegnet.

Manipulere outputtet, indtil det ligner det oprindelige OData-feed – en tabel med to kolonner: AirlineCode og Name.

Formaterede flyselskaber.

Den resulterende forespørgsel bør se nogenlunde sådan ud:

let
    Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines"),
    value = Source[value],
    toTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    expand = Table.ExpandRecordColumn(toTable, "Column1", {"AirlineCode", "Name"}, {"AirlineCode", "Name"})
in
    expand

Giv forespørgslen et navn ("Airlines").

Opret en ny tom forespørgsel. Denne gang skal du bruge funktionen TripPin.Feed til at få adgang til objektet /Airports. Anvend transformeringer, indtil du får noget, der ligner det share, der vises nedenfor. Den tilsvarende forespørgsel kan også findes nedenfor – giv også denne forespørgsel et navn ("Lufthavne").

Formaterede lufthavne.

let
    Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airports"),
    value = Source[value],
    #"Converted to Table" = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"Name", "IcaoCode", "IataCode", "Location"}, {"Name", "IcaoCode", "IataCode", "Location"}),
    #"Expanded Location" = Table.ExpandRecordColumn(#"Expanded Column1", "Location", {"Address", "Loc", "City"}, {"Address", "Loc", "City"}),
    #"Expanded City" = Table.ExpandRecordColumn(#"Expanded Location", "City", {"Name", "CountryRegion", "Region"}, {"Name.1", "CountryRegion", "Region"}),
    #"Renamed Columns" = Table.RenameColumns(#"Expanded City",{{"Name.1", "City"}}),
    #"Expanded Loc" = Table.ExpandRecordColumn(#"Renamed Columns", "Loc", {"coordinates"}, {"coordinates"}),
    #"Added Custom" = Table.AddColumn(#"Expanded Loc", "Latitude", each [coordinates]{1}),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "Longitude", each [coordinates]{0}),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"coordinates"}),
    #"Changed Type" = Table.TransformColumnTypes(#"Removed Columns",{{"Name", type text}, {"IcaoCode", type text}, {"IataCode", type text}, {"Address", type text}, {"City", type text}, {"CountryRegion", type text}, {"Region", type text}, {"Latitude", type number}, {"Longitude", type number}})
in
    #"Changed Type"

Du kan gentage denne proces for at få flere stier under tjenesten. Når du er klar, skal du gå videre til næste trin for at oprette en (mock)-navigationstabel.

Simulere en navigationstabel

Nu skal du oprette en tabel (ved hjælp af M-kode), der præsenterer dine pænt formaterede TripPin-enheder.

Start en ny tom forespørgsel, og hent Avanceret editor.

Indsæt følgende forespørgsel:

let
    source = #table({"Name", "Data"}, {
        { "Airlines", Airlines },
        { "Airports", Airports }
    })
in
    source

Hvis du ikke har angivet indstillingen for niveauer for beskyttelse af personlige oplysninger til "Ignorer altid indstillinger for niveau for beskyttelse af personlige oplysninger" (også kaldet "Kombiner hurtigt"), får du vist en prompt om beskyttelse af personlige oplysninger.

Firewall.

Beskeder om beskyttelse af personlige oplysninger vises, når du kombinerer data fra flere kilder og endnu ikke har angivet et niveau for beskyttelse af personlige oplysninger for en eller flere kilder. Vælg knappen Fortsæt , og angiv niveauet for beskyttelse af personlige oplysninger for den øverste kilde til Offentlig.

Privatliv.

Vælg Gem , hvorefter tabellen vises. Selvom dette endnu ikke er en navigationstabel, indeholder den den grundlæggende funktionalitet, du skal bruge for at gøre den til en i en efterfølgende lektion.

FakeNav.

Der foretages ikke kontrol af datakombinationer, når du får adgang til flere datakilder fra en udvidelse. Da alle datakildekald, der foretages fra udvidelsen, arver den samme godkendelseskontekst, antages det, at de er "sikre" at kombinere. Din udvidelse behandles altid som en enkelt datakilde, når det gælder regler for datakombination. Brugerne modtager stadig de almindelige prompter om beskyttelse af personlige oplysninger, når de kombinerer din kilde med andre M-kilder.

Hvis du kører Fiddler og vælger knappen Opdater prøveversion i Power Query-editor, skal du notere de separate webanmodninger for hvert element i navigationstabellen. Dette angiver, at der sker en ivrig evaluering, hvilket ikke er ideelt, når du opretter navigationstabeller med mange elementer. Efterfølgende lektioner viser, hvordan du opretter en korrekt navigationstabel, der understøtter doven evaluering.

Konklusion

I denne lektion kan du se, hvordan du opretter en enkel connector til en REST-tjeneste. I dette tilfælde har du omdannet en eksisterende OData-udvidelse til en standard-REST-udvidelse (ved hjælp af Web.Contents), men de samme begreber gælder, hvis du oprettede en ny udvidelse fra bunden.

I den næste lektion skal du tage de forespørgsler, der er oprettet i denne lektion, ved hjælp af Power BI Desktop og omdanne dem til en sand navigationstabel i udvidelsen.

Næste trin

TripPin Del 3 – Navigationstabeller