TripPin deel 4: gegevensbronpaden
Deze meerdelige zelfstudie gaat over het maken van een nieuwe gegevensbronextensie voor Power Query. De zelfstudie is bedoeld om opeenvolgend te worden uitgevoerd elke les is gebaseerd op de connector die in de vorige lessen is gemaakt, en voegt incrementeel nieuwe mogelijkheden toe — aan uw connector.
In deze les gaat u het volgende doen:
- De verbindingslogica voor uw connector vereenvoudigen
- De navigatietabel verbeteren
Deze les vereenvoudigt de connector die in de vorige les is gebouwd door de vereiste functieparameters te verwijderen en de gebruikerservaring te verbeteren door over te gaan naar een dynamisch gegenereerde navigatietabel.
Zie de sectie Gegevensbronpaden van Verificatie verwerken voor een uitgebreide uitleg over hoe referenties worden geïdentificeerd.
Gegevensbronpaden
Bij het aanroepen van een gegevensbronfunctie identificeert de M-engine welke referenties moeten worden gebruikt tijdens een evaluatie door een opzoekactie uit te voeren op basis van de waarden Voor gegevensbron en Gegevensbronpad.
In de vorige les hebt u twee gegevensbronfuncties gedeeld, beide met één Uri.Type-parameter.
[DataSource.Kind="TripPin"]
shared TripPin.Feed = Value.ReplaceType(TripPinImpl, type function (url as Uri.Type) as any);
[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = Value.ReplaceType(TripPinNavTable, type function (url as Uri.Type) as any);
De eerste keer dat u een query uitvoert die gebruikmaakt van een van de functies, ontvangt u een referentieprompt met vervolgkeuzen waarmee u een pad en een verificatietype kunt selecteren.

Als u dezelfde query opnieuw uitvoert, met dezelfde parameters, kan de M-engine de referenties in de cache vinden en wordt er geen referentieprompt weergegeven. Als u het argument wijzigt in uw functie, zodat het basispad niet meer overeenkomt, wordt er een nieuwe referentieprompt url weergegeven voor het nieuwe pad.
U kunt alle referenties in de cache bekijken in de tabel Credentials in het venster M Query Output.

Afhankelijk van het type wijziging, resulteert het wijzigen van de parameters van uw functie waarschijnlijk in een referentiefout.
De connector vereenvoudigen
U vereenvoudigt nu uw connector door de parameters voor uw gegevensbronfunctie ( ) te TripPin.Contents verwijderen. U verwijdert ook de kwalificatie voor en laat deze als een functie die shared TripPin.Feed alleen intern is.
Een van de ontwerpinstellingen van Power Query is om het dialoogvenster voor de eerste gegevensbron zo eenvoudig mogelijk te houden. Indien mogelijk moet u de gebruiker opties bieden op navigatorniveau, in plaats van in het dialoogvenster Verbinding. Als een door de gebruiker opgegeven waarde programmatisch kan worden bepaald, kunt u deze toevoegen als het hoogste niveau van uw navigatietabel in plaats van een functieparameter.
Wanneer u bijvoorbeeld verbinding maakt met een relationele database, hebt u mogelijk server-, database- en tabelnamen nodig.
Zodra u weet met welke server verbinding moet worden gemaakt en de referenties zijn opgegeven, kunt u de API van de database gebruiken om een lijst met databases en een lijst met tabellen in elke database op te halen.
In dit geval moet alleen de servernaam een vereiste parameter zijn en de niveaus van uw navigatietabel zijn om uw eerste verbindingsdialoogvenster zo eenvoudig mogelijk — Database Table te houden.
Omdat de TripPin-service een vast URL-eindpunt heeft, hoeft u de gebruiker niet om waarden te vragen. U verwijdert de URL-parameter uit uw functie en definieert een BaseUrl-variabele in uw connector.
BaseUrl = "https://services.odata.org/v4/TripPinService/";
[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = () => TripPinNavTable(BaseUrl) as table;
U houdt de functie, maar maakt deze niet meer gedeeld, koppelt deze niet meer aan een soort gegevensbron en vereenvoudigt TripPin.Feed de declaratie. Vanaf dit moment gebruikt u deze alleen intern in dit sectiedocument.
TripPin.Feed = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Als u de aanroep in uw bestand bij te werken en deze in Visual Studio, ziet u een nieuwe TripPin.Contents() TripPin.query.pq referentieprompt. Houd er rekening mee dat er nu één gegevensbronpadwaarde — TripPin is.

De navigatietabel verbeteren
In de eerste zelfstudie hebt u de ingebouwde functies OData gebruikt om verbinding te maken met de TripPin-service.
Dit heeft u een echt mooi ogende navigatietabel gegeven, gebaseerd op het TripPin-servicedocument, zonder extra code aan uw zijde.
De functie OData.Feed heeft automatisch het harde werk voor u gedaan.
Omdat u het 'ruw' maakt met Web.Contents in plaats van OData.Feed,moet u deze navigatietabel zelf opnieuw maken.

U gaat de volgende wijzigingen aanbrengen:
- Een lijst met items definiëren die in uw navigatietabel moeten worden weergegeven
- De entiteitsspecifieke functies (
GetAirlineTablesen ) zijn niet meerGetAirportsTablenodig
Een navigatietabel genereren vanuit een lijst
U maakt een lijst met de entiteiten die u wilt blootstellen in de navigatietabel en bouwt de juiste URL om er toegang toe te krijgen. Omdat alle entiteiten zich onder hetzelfde hoofdpad vallen, kunt u deze URL's dynamisch bouwen.
Ter vereenvoudiging van het voorbeeld maakt u alleen de drie entiteitssets beschikbaar (Luchtvaartmaatschappij, Luchthavens, Personen), die beschikbaar worden gemaakt als tabellen in M, en slaat u de singleton (Ik) over die als een record zou worden blootgesteld. U slaat het toevoegen van de functies over tot een latere les.
RootEntities = {
"Airlines",
"Airports",
"People"
};
Vervolgens werkt u uw functie TripPinNavTable bij om de tabel een kolom tegelijk te maken.
De kolom [Data] voor elke entiteit wordt opgehaald door aan te TripPin.Feed roepen met de volledige URL naar de entiteit.
TripPinNavTable = (url as text) as table =>
let
entitiesAsTable = Table.FromList(RootEntities, Splitter.SplitByNothing()),
rename = Table.RenameColumns(entitiesAsTable, {{"Column1", "Name"}}),
// Add Data as a calculated column
withData = Table.AddColumn(rename, "Data", each TripPin.Feed(Uri.Combine(url, [Name])), Uri.Type),
// Add ItemKind and ItemName as fixed text values
withItemKind = Table.AddColumn(withData, "ItemKind", each "Table", type text),
withItemName = Table.AddColumn(withItemKind, "ItemName", each "Table", type text),
// Indicate that the node should not be expandable
withIsLeaf = Table.AddColumn(withItemName, "IsLeaf", each true, type logical),
// Generate the nav table
navTable = Table.ToNavigationTable(withIsLeaf, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
in
navTable;
Wanneer u dynamisch URL-paden bouwt, moet u ervoor zorgen dat u weet waar uw slashes (/) zich vooraan zijn! Houd er rekening mee dat URI.Combine de volgende regels gebruikt bij het combineren van paden:
- Wanneer de
relativeUriparameter begint met een /, wordt het hele pad van de parameterbaseUrivervangen - Als de
relativeUriparameter niet begint met een / en eindigt metbaseUrieen /, wordt het pad toegevoegd - Als de parameter niet begint met een / en eindigt niet met een /, wordt het
relativeUrilaatste segment van het padbaseUrivervangen
In de volgende afbeelding ziet u voorbeelden hiervan:

De entiteitsspecifieke functies verwijderen
Om het onderhoud van uw connector te vereenvoudigen, verwijdert u de entiteitsspecifieke opmaakfuncties die u in de vorige les en — GetAirlineTables hebt GetAirportsTable gebruikt.
In plaats daarvan werkt u bij om het JSON-antwoord te verwerken op een manier die TripPin.Feed werkt voor al uw entiteiten.
U neemt met name het value veld van de geretourneerde OData JSON-nettolading en converteert deze van een lijst met records naar een tabel.
TripPin.Feed = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source),
// The response is a JSON record - the data we want is a list of records in the "value" field
value = json[value],
asTable = Table.FromList(value, Splitter.SplitByNothing()),
// expand all columns from the record
fields = Record.FieldNames(Table.FirstValue(asTable, [Empty = null])),
expandAll = Table.ExpandRecordColumn(asTable, "Column1", fields)
in
expandAll;
Notitie
Een nadeel van het gebruik van een algemene benadering voor het verwerken van uw entiteiten is dat u de mooie indeling en type-informatie voor uw entiteiten kwijt bent. In een latere sectie in deze zelfstudie ziet u hoe u een schema kunt afdwingen voor REST API-aanroepen.
Conclusie
In deze zelfstudie hebt u uw connector opgeschoond en vereenvoudigd door de waarde van uw gegevensbronpad te herstellen en over te gaan naar een flexibelere indeling voor uw navigatietabel. Nadat u deze stappen (of met behulp van de voorbeeldcode in deze map) heeft doorlopen, retourneert de functie een TripPin.Contents navigatietabel in Power BI Desktop.
