TripPin část 2 – Datový konektor pro službu REST
Tento vícedílný kurz popisuje vytvoření nového rozšíření zdroje dat pro Power Query. Tento kurz se má provést postupně – každá lekce vychází z konektoru vytvořeného v předchozích lekcích a postupně přidává do konektoru nové funkce.
V této lekci:
- Vytvoření základní funkce, která volá rozhraní REST API pomocí Web.Contents
- Zjistěte, jak nastavit hlavičky požadavků a zpracovat odpověď JSON.
- Použití Power BI Desktopu k uspořádání odpovědi do uživatelsky přívětivého formátu
Tato lekce převede konektor založený na OData pro službu TripPin (vytvořený v předchozí lekci) na konektor, který se podobá něčemu, co byste vytvořili pro jakékoli rozhraní RESTful API. OData je rozhraní RESTful API, ale jedno s pevnou sadou konvencí. Výhodou OData je, že poskytuje schéma, protokol načítání dat a standardní dotazovací jazyk. Když použijete OData.Feed , budeme vyžadovat, abychom tyto funkce do konektoru vytvořili sami.
Rekapitulace konektoru OData
Než z konektoru odeberete funkce OData, pojďme si rychle projít, co aktuálně dělá (většinou na pozadí) k načtení dat ze služby.
Otevřete projekt rozšíření TripPin z části 1 v editoru Visual Studio Code. Otevřete soubor dotazu a vložte následující dotaz:
TripPin.Feed("https://services.odata.org/v4/TripPinService/Me")
Otevřete Fiddler a vyhodnoťte aktuální soubor Power Query v editoru Visual Studio Code.
Ve Fiddleru existují tři požadavky na server:
/Me
– skutečná adresa URL, kterou požadujete./$metadata
– volání automaticky provedenéOData.Feed
funkcí k určení schématu a typových informací o odpovědi./Me/BestFriend
— jedno z polí, která byla (dychtivě) vytažena, když jste vypsali /Me singleton. V takovém případě volání vedlo ke204 No Content
stavu.
Hodnocení M je většinou opožděné. Ve většině případů se datové hodnoty načítají nebo načítají jenom v případě potřeby. Existují scénáře (například případ /Me/BestFriend), kdy se hodnota načte dychtivě. K tomu obvykle dochází, když jsou informace o typu potřebné pro člen a modul nemá žádný jiný způsob, jak určit typ, než načíst hodnotu a zkontrolovat ji. Líné věci (tj. vyhnout se dychtivým tahům) je jedním z klíčových aspektů, jak zajistit výkon konektoru M.
Všimněte si hlaviček požadavků, které byly odeslány spolu s požadavky a formátem JSON odpovědi požadavku /Me.
{
"@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
}
Po dokončení vyhodnocení dotazu by okno výsledku PQTest mělo zobrazit hodnotu záznamu pro me singleton.
Pokud porovnáte pole ve výstupním okně s poli vrácenými v nezpracované odpovědi JSON, všimnete si neshody. Výsledek dotazu obsahuje další pole (Friends
, Trips
, GetFriendsTrips
), která se v odpovědi JSON nezobrazují nikde. Funkce OData.Feed automaticky připojila tato pole k záznamu na základě schématu vráceného $metadata. Toto je dobrý příklad, jak může konektor rozšířit nebo přeformátovat odpověď ze služby, aby poskytoval lepší uživatelské prostředí.
Vytvoření základního konektoru REST
Teď do konektoru, který volá Web.Contents, přidáte novou exportovanou funkci.
Abyste však mohli úspěšně provádět webové požadavky do služby OData, budete muset nastavit některé standardní hlavičky OData. Uděláte to tak, že v konektoru definujete společnou sadu hlaviček jako novou proměnnou:
DefaultRequestHeaders = [
#"Accept" = "application/json;odata.metadata=minimal", // column name and values only
#"OData-MaxVersion" = "4.0" // we only support v4
];
Svou implementaci funkce TripPin.Feed
změníte tak, aby místo použití OData.Feed
web.Contents k vytvoření webového požadavku používala webovou žádost a parsuje výsledek jako dokument JSON.
TripPinImpl = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Nezapomeňte vytvořit konektor teď, když jste provedli změny v souboru konektoru. Pak můžete vyhodnotit soubor dotazu (TripPin.query.pq). Výsledek záznamu /Me se teď podobá nezpracovanému formátu JSON, který jste viděli v požadavku Fiddler.
Pokud při spuštění nové funkce sledujete Fiddleru, všimněte si také, že vyhodnocení teď vytvoří jeden webový požadavek, nikoli tři. Blahopřejeme – dosáhli jste 300% zvýšení výkonu! Teď jste ztratili všechny informace o typu a schématu, ale zatím se na tuto část nemusíte soustředit.
Aktualizujte svůj dotaz tak, aby přistupoval k některým entitě nebo tabulkám TripPin, například:
https://services.odata.org/v4/TripPinService/Airlines
https://services.odata.org/v4/TripPinService/Airports
https://services.odata.org/v4/TripPinService/Me/Trips
Všimněte si, že cesty, které se použily k vrácení pěkně formátovaných tabulek, teď vrací pole "hodnota" nejvyšší úrovně s vloženým [Seznamem]. Abyste je mohli použít pro scénáře spotřeby koncových uživatelů, musíte u výsledku udělat několik transformací.
Vytváření transformací v Power Query
I když je možné transformace jazyka M vytvářet ručně, většina lidí preferuje, aby data tvarovali pomocí Power Query. Rozšíření otevřete v Power BI Desktopu a použijete ho k návrhu dotazů, aby se výstup převést na uživatelsky přívětivější formát. Znovu sestavte řešení, zkopírujte nový soubor s příponou do adresáře Custom Data Připojení or a znovu spusťte Power BI Desktop.
Spusťte nový prázdný dotaz a vložte do řádku vzorců následující:
= TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines")
Nezapomeňte uvést znaménko =.
Manipulujte s výstupem, dokud nebude vypadat jako původní datový kanál OData – tabulka se dvěma sloupci: AirlineCode a Name.
Výsledný dotaz by měl vypadat přibližně takto:
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
Zadejte název dotazu ("Airlines").
Vytvořte nový prázdný dotaz. Tentokrát použijte TripPin.Feed
funkci pro přístup k entitě /Airport. Použijte transformace, dokud se nezobrazí něco podobného sdílené složce zobrazené níže. Odpovídající dotaz najdete také níže – dejte tomuto dotazu také název ("Letiště").
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"
Tento proces můžete opakovat pro více cest v rámci služby. Až budete připraveni, přejděte k dalšímu kroku vytvoření (napodobené) navigační tabulky.
Simulace navigační tabulky
Teď sestavíte tabulku (pomocí kódu M), která představuje dobře naformátované entity TripPin.
Spusťte nový prázdný dotaz a vyvolejte Rozšířený editor.
Vložte následující dotaz:
let
source = #table({"Name", "Data"}, {
{ "Airlines", Airlines },
{ "Airports", Airports }
})
in
source
Pokud jste nenastavili nastavení Úrovně ochrany osobních údajů na hodnotu Vždy ignorovat nastavení úrovně ochrany osobních údajů (označované také jako Rychlé kombinování), zobrazí se výzva k ochraně osobních údajů.
Při kombinování dat z více zdrojů se zobrazí výzvy k ochraně osobních údajů a ještě jste pro jeden nebo více zdrojů nezadali úroveň ochrany osobních údajů. Vyberte tlačítko Pokračovat a nastavte úroveň ochrany osobních údajů nejvyššího zdroje na Veřejné.
Vyberte Uložit a zobrazí se tabulka. I když to ještě není navigační tabulka, poskytuje základní funkce, které potřebujete v další lekci převést na jednu z nich.
Při přístupu k více zdrojům dat z rozšíření nedojde k kontrolám kombinace dat. Vzhledem k tomu, že všechna volání zdroje dat provedená v rámci rozšíření dědí stejný kontext autorizace, předpokládá se, že jsou "bezpečné", aby bylo možné kombinovat. Vaše rozšíření bude vždy považováno za jeden zdroj dat, pokud jde o pravidla kombinace dat. Uživatelé by stále dostávali běžné výzvy k ochraně osobních údajů při kombinování zdroje s jinými zdroji M.
Pokud spustíte Fiddler a v Editor Power Query vyberete tlačítko Aktualizovat náhled, všimněte si samostatných webových požadavků pro každou položku v navigační tabulce. To znamená, že probíhá dychtivé vyhodnocení, které není ideální při vytváření navigačních tabulek s mnoha prvky. Následující lekce ukazují, jak vytvořit správnou navigační tabulku, která podporuje opožděné vyhodnocení.
Závěr
Tato lekce vám ukázala, jak vytvořit jednoduchý konektor pro službu REST. V tomto případě jste stávající rozšíření OData změnili na standardní rozšíření REST (pomocí Web.Contents), ale stejné koncepty platí i v případě, že jste vytvořili nové rozšíření úplně od začátku.
V další lekci použijete dotazy vytvořené v této lekci pomocí Power BI Desktopu a změníte je na skutečnou navigační tabulku v rámci rozšíření.