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.Feed
strony. 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).
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:
- Importowanie typowej
Table.GenerateByPage
funkcji - Dodawanie funkcji używanej
GetAllPagesByNextLink
Table.GenerateByPage
do łączenia wszystkich stron GetPage
Dodawanie funkcji, która może odczytywać jedną stronę danych- Dodawanie funkcji w
GetNextLink
celu wyodrębnienia następnego adresu URL z odpowiedzi - 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.
Implementowanie polecenia GetAllPagesByNextLink
Treść GetAllPagesByNextLink
funkcji implementuje getNextPage
argument funkcji dla Table.GenerateByPage
elementu . 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];
Implementowanie polecenia GetNextLink
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 GetAllPagesByNextLink
metody , 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.
Jeśli przyjrzysz się żądaniom w narzędziu fiddler, powinny być teraz widoczne oddzielne żądania dla każdej strony danych.
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.Document
usługi .