Megosztás a következőn keresztül:


TripPin 5. rész – Lapozás

Ez a többrészes oktatóanyag a Power Query új adatforrásbővítményének létrehozását ismerteti. Az oktatóanyagot egymás után kell elvégezni – minden lecke az előző leckékben létrehozott összekötőre épül, és növekményesen új képességeket ad hozzá az összekötőhöz.

Ebben a leckében a következőt fogja:

  • Lapozási támogatás hozzáadása az összekötőhöz

Számos Rest API "pages" formátumban ad vissza adatokat, így az ügyfeleknek több kérést kell küldenie az eredmények összefűzéséhez. Bár vannak gyakori konvenciók a lapozásra (például az RFC 5988-ra), általában API-tól API-ig terjed. Szerencsére a TripPin egy OData szolgáltatás, és az OData szabvány meghatározza a lapozás módját az odata.nextLink értékek használatával, amelyet a válasz törzsében ad vissza.

Az összekötő korábbi iterációinak egyszerűsítése érdekében a TripPin.Feed függvény nem volt lapérzékeny. Egyszerűen elemezte a kérésből visszaadott JSON-t, és táblázatként formázta. Azok, akik ismerik az OData protokollt, észrevehették, hogy számos helytelen feltételezés történt a válasz formátuma alapján (például feltételezve, hogy van egy value rekordtömböt tartalmazó mező).

Ebben a leckében a válaszkezelési logikát az oldal tudatossá tételével fejlesztheti. A jövőbeli oktatóanyagok robusztusabbá teszik az oldalkezelési logikát, és több válaszformátumot is képesek kezelni (beleértve a szolgáltatás hibáit is).

Feljegyzés

Nem kell saját lapozási logikát implementálnia az OData.Feeden alapuló összekötőkkel, mivel az automatikusan kezeli az egészet.

Lapozási ellenőrzőlista

A lapozási támogatás megvalósításakor az alábbi tudnivalókat kell tudnia az API-ról:

  • Hogyan kérheti le a következő adatoldalt?
  • A lapozási mechanizmus magában foglalja az értékek kiszámítását, vagy kinyeri a következő oldal URL-címét a válaszból?
  • Honnan tudja, mikor kell leállítani a lapozást?
  • Vannak olyan paraméterek a lapozással kapcsolatban, amelyekről tudnia kell? (például "oldalméret")

Ezekre a kérdésekre adott válasz hatással van a lapozási logika implementálására. Bár a lapozási implementációkban (például a Table.GenerateByPage használata) bizonyos mennyiségű kód újrafelhasználható, a legtöbb összekötő egyéni logikát igényel.

Feljegyzés

Ez a lecke egy OData-szolgáltatás lapozási logikáját tartalmazza, amely egy adott formátumot követ. Ellenőrizze az API dokumentációját, és állapítsa meg, hogy milyen módosításokat kell végrehajtania az összekötőben a lapozási formátum támogatásához.

Az OData-lapozás áttekintése

Az OData-lapozást a válasz hasznos adataiban található nextLink-széljegyzetek vezérlik. A nextLink érték a következő adatoldal URL-címét tartalmazza. Tudni fogja, hogy van-e egy másik adatoldal, ha egy mezőt keres odata.nextLink a legkülső objektumban a válaszban. Ha nincs odata.nextLink mező, az összes adatot elolvasta.

{
  "odata.context": "...",
  "odata.count": 37,
  "value": [
    { },
    { },
    { }
  ],
  "odata.nextLink": "...?$skiptoken=342r89"
}

Egyes OData-szolgáltatások lehetővé teszik az ügyfelek számára, hogy maximális oldalméret-beállítást adjanak, de a szolgáltatáson múlik, hogy betartják-e. A Power Querynek képesnek kell lennie bármilyen méretű válaszokat kezelni, így nem kell aggódnia az oldalméret-beállítások megadása miatt – bármilyen szolgáltatást támogathat.

A kiszolgálóalapú lapozással kapcsolatos további információk az OData specifikációjában találhatók.

TripPin tesztelése

A lapozási implementáció javítása előtt ellenőrizze a bővítmény aktuális viselkedését az előző oktatóanyagból. Az alábbi teszt lekérdezés lekéri a Kapcsolatok táblát, és hozzáad egy indexoszlopot az aktuális sorszám megjelenítéséhez.

let
    source = TripPin.Contents(),
    data = source{[Name="People"]}[Data],
    withRowCount = Table.AddIndexColumn(data, "Index")
in
    withRowCount

Kapcsolja be a Fiddlert, és futtassa a lekérdezést a Power Query SDK-ban. Vegye figyelembe, hogy a lekérdezés egy nyolc sorból (0–7. index) rendelkező táblát ad vissza.

QueryWithoutPaging.

Ha megtekinti a fiddler válaszának törzsét, látni fogja, hogy valójában tartalmaz egy @odata.nextLink mezőt, ami azt jelzi, hogy több oldalnyi adat áll rendelkezésre.

{
  "@odata.context": "https://services.odata.org/V4/TripPinService/$metadata#People",
  "@odata.nextLink": "https://services.odata.org/v4/TripPinService/People?%24skiptoken=8",
  "value": [
    { },
    { },
    { }
  ]
}

Lapozás implementálása a TripPinhez

Most a következő módosításokat fogja végrehajtani a bővítményen:

  1. A közös Table.GenerateByPage függvény importálása
  2. GetAllPagesByNextLink Olyan függvény hozzáadása, amely az összes oldal összefűzésére szolgál Table.GenerateByPage
  3. GetPage Egyetlen adatoldal beolvasására képes függvény hozzáadása
  4. GetNextLink Függvény hozzáadása a következő URL-cím kinyeréséhez a válaszból
  5. Frissítés TripPin.Feed az új lapolvasó függvények használatához

Feljegyzés

Az oktatóanyag korábbi részében leírtak szerint a lapozási logika adatforrásonként eltérő lesz. Az implementáció megpróbálja a logikát olyan függvényekre bontani, amelyek a válaszban visszaadott következő hivatkozásokat használó források számára újra felhasználhatók.

Table.GenerateByPage

Ha a forrás által visszaadott (potenciálisan) több lapot egyetlen táblába szeretné egyesíteni, a következőt használjuk Table.GenerateByPage: . Ez a függvény argumentumként egy getNextPage függvényt vesz fel, amelynek pontosan azt kell tennie, amit a neve sugall: lekéri a következő adatoldalt. Table.GenerateByPage ismételten meghívja a getNextPage függvényt, minden alkalommal, amikor átadja a legutóbbi híváskor létrehozott eredményeket, amíg vissza nem tér null , hogy jelezzen, hogy nincs több lap.

Mivel ez a függvény nem része a Power Query szokásos kódtárának, a forráskódot a .pq fájlba kell másolnia.

A függvény törzse GetAllPagesByNextLink implementálja a getNextPage függvény argumentumát Table.GenerateByPage. Meghívja a függvényt GetPage , és lekéri a következő adatoldal URL-címét a NextLink meta rekord mezőjéből az előző hívásból.

// Read all pages of data.
// After every page, we check the "NextLink" record on the metadata of the previous request.
// Table.GenerateByPage will keep asking for more pages until we return null.
GetAllPagesByNextLink = (url as text) as table =>
    Table.GenerateByPage((previous) => 
        let
            // if previous is null, then this is our first page of data
            nextLink = if (previous = null) then url else Value.Metadata(previous)[NextLink]?,
            // if NextLink was set to null by the previous call, we know we have no more data
            page = if (nextLink <> null) then GetPage(nextLink) else null
        in
            page
    );

GetPage implementálása

A GetPage függvény a Web.Contents használatával egyetlen adatlapot kér le a TripPin szolgáltatásból, és a választ táblázattá alakítja. A Web.Contents válaszát átadja a függvénynek a GetNextLink következő oldal URL-címének kinyeréséhez, majd a visszaadott tábla (adatoldal) rekordjára állítjameta.

Ez az implementáció a hívás kissé módosított verziója az TripPin.Feed előző oktatóanyagokból.

GetPage = (url as text) as table =>
    let
        response = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),        
        body = Json.Document(response),
        nextLink = GetNextLink(body),
        data = Table.FromRecords(body[value])
    in
        data meta [NextLink = nextLink];

A GetNextLink függvény egyszerűen ellenőrzi a válasz törzsét egy @odata.nextLink mezőnél, és visszaadja annak értékét.

// In this implementation, 'response' will be the parsed body of the response after the call to Json.Document.
// Look for the '@odata.nextLink' field and simply return null if it doesn't exist.
GetNextLink = (response) as nullable text => Record.FieldOrDefault(response, "@odata.nextLink");

Végső összeállítás

A lapozási logika implementálásának utolsó lépése az új függvények használatára való frissítés TripPin.Feed . Egyelőre egyszerűen csak behívja GetAllPagesByNextLink, de a későbbi oktatóanyagokban új képességeket fog hozzáadni (például séma kényszerítését és lekérdezési paraméterlogikát).

TripPin.Feed = (url as text) as table => GetAllPagesByNextLink(url);

Ha ugyanazt a teszt lekérdezést futtatja újra az oktatóanyag korábbi szakaszából, most már működés közben kell látnia az oldalolvasót. Azt is látnia kell, hogy nyolc helyett 24 sor van a válaszban.

QueryWithPaging.

Ha a Fiddlerben tekinti meg a kéréseket, akkor mostantól külön kéréseket kell látnia az egyes adatoldalakhoz.

Hegedűs.

Feljegyzés

Ismétlődő kéréseket fog látni a szolgáltatás első oldalára vonatkozóan, ami nem ideális. A további kérés az M motor sémaellenőrzési viselkedésének eredménye. Egyelőre hagyja figyelmen kívül ezt a problémát, és oldja meg a következő oktatóanyagban, amelyben explicit sémát fog alkalmazni.

Összegzés

Ez a lecke bemutatta, hogyan implementálhat lapozási támogatást egy Rest API-hoz. Bár a logika valószínűleg eltérő lesz az API-k között, az itt létrehozott mintának kisebb módosításokkal újra felhasználhatónak kell lennie.

A következő leckében azt vizsgáljuk meg, hogyan alkalmazhat explicit sémát az adatokra, túllépve a kapott egyszerű text és number adattípusokon Json.Document.

Következő lépések

TripPin 6. rész – Séma