Udostępnij za pośrednictwem


TripPin — część 5 — stronicowanie

Ten wieloczęściowy samouczek obejmuje tworzenie nowego rozszerzenia źródła danych dla dodatku Power Query. Samouczek ma być wykonywany sekwencyjnie — każda lekcja opiera się na łączniku utworzonym w poprzednich lekcjach, przyrostowo dodając nowe możliwości do łącznika.

W tej lekcji wykonasz następujące lekcji:

  • Dodawanie obsługi stronicowania do łącznika

Wiele interfejsów API REST zwraca dane na "stronach", co wymaga od klientów wykonania wielu żądań w celu połączenia wyników. Chociaż istnieją pewne typowe konwencje dotyczące stronicowania (na przykład RFC 5988), zwykle różni się ona od interfejsu API do interfejsu API. Na szczęście TripPin jest usługą OData, a standard OData definiuje sposób stronicowania przy użyciu wartości odata.nextLink zwróconych w treści odpowiedzi.

Aby uprościć poprzednie iteracji łącznika, funkcja nie była świadoma TripPin.Feedstrony. Po prostu przeanalizowano dowolny kod JSON zwrócony z żądania i sformatował go jako tabelę. Osoby zaznajomione z protokołem OData mogły zauważyć, że wiele nieprawidłowych założeń zostało założeń w formacie odpowiedzi (na przykład przy założeniu, że istnieje value pole zawierające tablicę rekordów).

W tej lekcji ulepszysz logikę obsługi odpowiedzi, rozpoznając ją na stronie. Przyszłe samouczki sprawiają, że logika obsługi stron jest bardziej niezawodna i umożliwia obsługę wielu formatów odpowiedzi (w tym błędów z usługi).

Uwaga

Nie trzeba implementować własnej logiki stronicowania z łącznikami opartymi na protokole OData.Feed, ponieważ automatycznie obsługuje je wszystko.

Lista kontrolna stronicowania

Podczas implementowania obsługi stronicowania należy znać następujące kwestie dotyczące interfejsu API:

  • Jak zażądać następnej strony danych?
  • Czy mechanizm stronicowania obejmuje obliczanie wartości, czy wyodrębniasz adres URL następnej strony z odpowiedzi?
  • Jak sprawdzić, kiedy zatrzymać stronicowanie?
  • Czy istnieją parametry związane z stronicowaniem, o których należy pamiętać? (na przykład "rozmiar strony")

Odpowiedź na te pytania ma wpływ na sposób implementowania logiki stronicowania. Chociaż w implementacjach stronicowania jest używana pewna ilość kodu (na przykład użycie metody Table.GenerateByPage, większość łączników wymaga logiki niestandardowej.

Uwaga

Ta lekcja zawiera logikę stronicowania dla usługi OData, która jest zgodna z określonym formatem. Zapoznaj się z dokumentacją interfejsu API, aby określić zmiany, które należy wprowadzić w łączniku, aby obsługiwać jego format stronicowania.

Omówienie stronicowania OData

Stronicowanie OData jest sterowane przez adnotacje nextLink zawarte w ładunku odpowiedzi. Wartość nextLink zawiera adres URL do następnej strony danych. Dowiesz się, czy istnieje inna strona danych, wyszukując odata.nextLink pole w najbardziej zewnętrznym obiekcie w odpowiedzi. Jeśli nie ma odata.nextLink pola, odczytasz wszystkie dane.

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

Niektóre usługi OData umożliwiają klientom dostarczanie preferencji maksymalnego rozmiaru strony, ale jest to usługa, czy ją przestrzegać. Dodatek Power Query powinien mieć możliwość obsługi odpowiedzi o dowolnym rozmiarze, więc nie musisz martwić się o określanie preferencji rozmiaru strony — możesz obsługiwać wszystkie elementy zgłaszane przez usługę.

Więcej informacji na temat stronicowania opartego na serwerze można znaleźć w specyfikacji OData.

Testowanie TripPin

Przed naprawieniem implementacji stronicowania potwierdź bieżące zachowanie rozszerzenia z poprzedniego samouczka. Poniższe zapytanie testowe pobiera tabelę Osoby i dodaje kolumnę indeksu, aby pokazać bieżącą liczbę wierszy.

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

Włącz program Fiddler i uruchom zapytanie w zestawie POWER Query SDK. Zwróć uwagę, że zapytanie zwraca tabelę z ośmioma wierszami (indeks od 0 do 7).

QueryWithoutPaging.

Jeśli spojrzysz na treść odpowiedzi z narzędzia fiddler, zobaczysz, że w rzeczywistości zawiera @odata.nextLink ono pole, co oznacza, że jest dostępnych więcej stron danych.

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

Implementowanie stronicowania dla elementu TripPin

Teraz wprowadzisz następujące zmiany w rozszerzeniu:

  1. Importowanie typowej Table.GenerateByPage funkcji
  2. Dodawanie funkcji używanej GetAllPagesByNextLink Table.GenerateByPage do łączenia wszystkich stron
  3. GetPage Dodawanie funkcji, która może odczytywać jedną stronę danych
  4. Dodawanie funkcji w GetNextLink celu wyodrębnienia następnego adresu URL z odpowiedzi
  5. Aktualizacja TripPin.Feed w celu korzystania z nowych funkcji czytnika stron

Uwaga

Jak wspomniano wcześniej w tym samouczku, logika stronicowania będzie się różnić między źródłami danych. Implementacja w tym miejscu próbuje podzielić logikę na funkcje, które powinny być wielokrotnego użytku dla źródeł, które używają następnych linków zwróconych w odpowiedzi.

Table.GenerateByPage

Aby połączyć (potencjalnie) wiele stron zwróconych przez źródło w jedną tabelę, użyjemy polecenia Table.GenerateByPage. Ta funkcja przyjmuje jako argument getNextPage funkcję, która powinna robić tylko to, co sugeruje jego nazwa: pobierz następną stronę danych. Table.GenerateByPage funkcja będzie wielokrotnie wywoływana getNextPage , za każdym razem przekazując wyniki wygenerowane podczas ostatniego wywołania, dopóki nie powróci null do sygnału z powrotem, że nie są dostępne żadne strony.

Ponieważ ta funkcja nie jest częścią standardowej biblioteki dodatku Power Query, musisz skopiować kod źródłowy do pliku pq.

Treść GetAllPagesByNextLink funkcji implementuje getNextPage argument funkcji dla Table.GenerateByPageelementu . Wywoła GetPage funkcję i pobierze adres URL następnej strony danych z NextLink pola rekordu meta z poprzedniego wywołania.

// 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
    );

Implementowanie programu GetPage

Funkcja GetPage będzie używać funkcji Web.Contents do pobierania pojedynczej strony danych z usługi TripPin i konwertowania odpowiedzi na tabelę. Przekazuje odpowiedź z Web.Contents do GetNextLink funkcji w celu wyodrębnienia adresu URL następnej strony i ustawia ją na meta rekord zwróconej tabeli (strona danych).

Ta implementacja jest nieco zmodyfikowaną wersją TripPin.Feed wywołania z poprzednich samouczków.

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];

Funkcja GetNextLink po prostu sprawdza treść odpowiedzi dla @odata.nextLink pola i zwraca jej wartość.

// 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");

Zebranie wszystkich elementów

Ostatnim krokiem implementacji logiki stronicowania jest aktualizacja TripPin.Feed w celu korzystania z nowych funkcji. Na razie po prostu wywołujesz metodę do GetAllPagesByNextLinkmetody , ale w kolejnych samouczkach dodasz nowe możliwości (takie jak wymuszanie schematu i logika parametrów zapytania).

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

Jeśli ponownie uruchomisz to samo zapytanie testowe z wcześniejszej wersji samouczka, teraz powinien zostać wyświetlony czytnik stron w akcji. Powinna być również widoczna liczba 24 wierszy w odpowiedzi, a nie osiem.

ZapytanieWithPaging.

Jeśli przyjrzysz się żądaniom w narzędziu fiddler, powinny być teraz widoczne oddzielne żądania dla każdej strony danych.

Skrzypek.

Uwaga

Zauważysz zduplikowane żądania dla pierwszej strony danych z usługi, co nie jest idealne. Dodatkowe żądanie jest wynikiem zachowania sprawdzania schematu aparatu M. Zignoruj ten problem na razie i rozwiąż go w następnym samouczku, w którym zastosujesz jawny schemat.

Podsumowanie

W tej lekcji pokazano, jak zaimplementować obsługę stronicowania dla interfejsu API REST. Chociaż logika prawdopodobnie będzie się różnić między interfejsami API, wzorzec ustanowiony w tym miejscu powinien być wielokrotnego użytku z drobnymi modyfikacjami.

W następnej lekcji dowiesz się, jak zastosować jawny schemat do danych, wykraczając poza proste text typy number danych uzyskanych z Json.Documentusługi .

Następne kroki

TripPin — część 6 — schemat