Κοινή χρήση μέσω


TripPin μέρος 5 - Σελιδοποίησης

Αυτή η εκμάθηση πολλαπλών τμημάτων καλύπτει τη δημιουργία μιας νέας επέκτασης προέλευσης δεδομένων για το Power Query. Το εκπαιδευτικό βοήθημα προορίζεται να γίνει διαδοχικά. Κάθε μάθημα βασίζεται στη σύνδεση που δημιουργήθηκε σε προηγούμενα μαθήματα, προσθέτοντας σταδιακά νέες δυνατότητες στη σύνδεσή σας.

Σε αυτό το μάθημα, θα κάνετε τα εξής:

  • Προσθήκη υποστήριξης σελιδοποίησης στη σύνδεση

Πολλά API Rest επιστρέφουν δεδομένα στις "σελίδες", απαιτώντας από τα προγράμματα-πελάτες να υποβάλουν πολλαπλές αιτήσεις για να ράψουν τα αποτελέσματα μαζί. Παρόλο που υπάρχουν ορισμένες κοινές συμβάσεις για τη σελιδοποίηση (όπως RFC 5988), γενικά ποικίλλει από API σε API. Ευτυχώς, το TripPin είναι μια υπηρεσία OData και το πρότυπο OData ορίζει έναν τρόπο πραγματοποίησης σελιδοποίησης χρησιμοποιώντας τις τιμές odata.nextLink που επιστρέφονται στο σώμα της απόκρισης.

Για να απλοποιήσει προηγούμενες επαναλήψεις της σύνδεσης, η συνάρτηση δεν γνώριζε τη TripPin.Feed σελίδα. Απλώς ανέλυσε οποιοδήποτε JSON επέστρεψε από την αίτηση και το μορφοποιεί ως πίνακα. Όσοι είναι εξοικειωμένοι με το πρωτόκολλο OData μπορεί να έχουν παρατηρήσει ότι έγιναν πολλές λανθασμένες υποθέσεις σχετικά με τη μορφή της απόκρισης (όπως υποθέτοντας ότι υπάρχει ένα value πεδίο που περιέχει έναν πίνακα εγγραφών).

Σε αυτό το μάθημα, βελτιώνετε τη λογική χειρισμού των αποκρίσεων, κάνοντας τη σελίδα ενήμερο. Τα μελλοντικά προγράμματα εκμάθησης καθιστούν τη λογική χειρισμού σελίδων πιο ισχυρή και ικανή να χειρίζεται πολλαπλές μορφές απόκρισης (συμπεριλαμβανομένων σφαλμάτων από την υπηρεσία).

Σημείωμα

Δεν χρειάζεται να υλοποιήσετε τη δική σας λογική σελιδοποίησης με συνδέσεις που βασίζονται στο OData.Feed, καθώς τα χειρίζεται όλα αυτόματα για εσάς.

Λίστα ελέγχου σελιδοποίησης

Κατά την υλοποίηση υποστήριξης σελιδοποίησης, θα πρέπει να γνωρίζετε τα ακόλουθα στοιχεία σχετικά με το API σας:

  • Πώς ζητάτε την επόμενη σελίδα δεδομένων;
  • Ο μηχανισμός σελιδοποίησης περιλαμβάνει τον υπολογισμό τιμών ή κάνετε εξαγωγή της διεύθυνσης URL για την επόμενη σελίδα από την απόκριση;
  • Πώς ξέρεις πότε να σταματάς τη σελιδοποίησης;
  • Υπάρχουν παράμετροι που σχετίζονται με τη σελιδοποίησης που πρέπει να γνωρίζετε; (όπως "μέγεθος σελίδας")

Η απάντηση σε αυτές τις ερωτήσεις επηρεάζει τον τρόπο με τον οποίο υλοποιείτε τη λογική σελιδοποίησης. Παρόλο που υπάρχει αρκετή επαναχρησιμοποίηση κώδικα στις υλοποιήσεις σελιδοποίησης (όπως η χρήση του Table.GenerateByPage, οι περισσότερες συνδέσεις θα καταλήξουν να απαιτούν προσαρμοσμένη λογική.

Σημείωμα

Αυτό το μάθημα περιέχει λογική σελιδοποίησης για μια υπηρεσία OData, η οποία ακολουθεί μια συγκεκριμένη μορφή. Ελέγξτε την τεκμηρίωση του API σας για να προσδιορίσετε τις αλλαγές που θα χρειαστεί να κάνετε στη σύνδεσή σας για να υποστηρίξετε τη μορφή σελιδοποίησης.

Επισκόπηση της σελιδοποίησης OData

Η σελιδοποίηση OData οδηγείται από τα σχόλια nextLink που περιέχονται στο ωφέλιμο φορτίο απόκρισης. Η τιμή nextLink περιέχει τη διεύθυνση URL για την επόμενη σελίδα δεδομένων. Θα γνωρίζετε εάν υπάρχει μια άλλη σελίδα δεδομένων, αναζητώντας ένα odata.nextLink πεδίο σε εξωτερικό αντικείμενο στην απόκριση. Εάν δεν odata.nextLink υπάρχει πεδίο, έχετε διαβάσει όλα τα δεδομένα σας.

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

Ορισμένες υπηρεσίες OData επιτρέπουν στους πελάτες να παρέχουν μια μέγιστη προτίμηση μεγέθους σελίδας, αλλά εξαρτάται από την υπηρεσία αν θα την τηρήσει ή όχι. Το Power Query θα πρέπει να μπορεί να χειρίζεται αποκρίσεις οποιουδήποτε μεγέθους, επομένως δεν χρειάζεται να ανησυχείτε για τον καθορισμό μιας προτίμησης μεγέθους σελίδας. Μπορείτε να υποστηρίξετε οτιδήποτε σας πετάει η υπηρεσία.

Μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με τη σελιδοποίησης βάσει διακομιστή στην προδιαγραφή OData.

Δοκιμή του TripPin

Προτού διορθώσετε την υλοποίηση σελιδοποίησης, επιβεβαιώστε την τρέχουσα συμπεριφορά της επέκτασης από την προηγούμενη εκμάθηση. Το παρακάτω ερώτημα δοκιμής ανακτά τον πίνακα Άτομα και προσθέτει μια στήλη ευρετηρίου για να εμφανίσει το τρέχον πλήθος γραμμών.

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

Ενεργοποιήστε το Fiddler και εκτελέστε το ερώτημα στο SDK του Power Query. Σημειώστε ότι το ερώτημα επιστρέφει έναν πίνακα με οκτώ γραμμές (ευρετήριο 0 έως 7).

QueryWithoutPaging.

Εάν κοιτάξετε το σώμα της απόκρισης από το fiddler, θα δείτε ότι στην πραγματικότητα περιέχει ένα @odata.nextLink πεδίο, υποδεικνύοντας ότι υπάρχουν περισσότερες σελίδες διαθέσιμων δεδομένων.

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

Υλοποίηση σελιδοποίησης για το TripPin

Τώρα θα κάνετε τις ακόλουθες αλλαγές στην επέκτασή σας:

  1. Εισαγωγή της κοινής Table.GenerateByPage συνάρτησης
  2. Προσθέστε μια GetAllPagesByNextLink συνάρτηση που χρησιμοποιεί Table.GenerateByPage για να κολλήσει όλες τις σελίδες μαζί
  3. Προσθέστε μια GetPage συνάρτηση που μπορεί να διαβάσει μία μόνο σελίδα δεδομένων
  4. Προσθήκη συνάρτησης GetNextLink για εξαγωγή της επόμενης διεύθυνσης URL από την απόκριση
  5. Ενημέρωση TripPin.Feed για χρήση των συναρτήσεων νέου προγράμματος ανάγνωσης σελίδας

Σημείωμα

Όπως αναφέρθηκε παραπάνω σε αυτό το εκπαιδευτικό βοήθημα, η λογική σελιδοποίησης θα διαφέρει μεταξύ των προελεύσεων δεδομένων. Η υλοποίηση εδώ προσπαθεί να διασπάσει τη λογική σε συναρτήσεις που θα πρέπει να επαναχρησιμοποιηθούν για προελεύσεις που χρησιμοποιούν τις επόμενες συνδέσεις που επιστρέφονται στην απόκριση.

Table.GenerateByPage

Για να συνδυάσουμε τις (πιθανώς) πολλαπλές σελίδες που επιστρέφονται από την προέλευση σε έναν μοναδικό πίνακα, θα χρησιμοποιήσουμε Table.GenerateByPage. Αυτή η συνάρτηση λαμβάνει ως όρισμα μια getNextPage συνάρτηση που θα πρέπει να κάνει ακριβώς αυτό που υποδηλώνει το όνομά της: να λάβει την επόμενη σελίδα δεδομένων. Table.GenerateByPage Η θα καλεί επανειλημμένα τη getNextPage συνάρτηση, κάθε φορά που τη διαβιβάζει, τα αποτελέσματα παρήγαγαν την τελευταία φορά που κλήθηκε, μέχρι να επιστρέψει null το μήνυμα ότι δεν υπάρχουν άλλες διαθέσιμες σελίδες.

Δεδομένου ότι αυτή η συνάρτηση δεν αποτελεί μέρος της τυπικής βιβλιοθήκης του Power Query, θα χρειαστεί να αντιγράψετε τον πηγαίο κώδικά της στο αρχείο .pq.

Το σώμα της συνάρτησης GetAllPagesByNextLink υλοποιεί το getNextPage όρισμα συνάρτησης για Table.GenerateByPage. Θα καλέσει τη GetPage συνάρτηση και θα ανακτήσει τη διεύθυνση URL για την επόμενη σελίδα δεδομένων από το NextLink πεδίο της meta εγγραφής από την προηγούμενη κλήση.

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

Η συνάστασή σας GetPage θα χρησιμοποιήσει το Web.Contents για να ανακτήσει μια μοναδική σελίδα δεδομένων από την υπηρεσία TripPin και να μετατρέψει την απόκριση σε πίνακα. Διαβιβάζει την απόκριση από το Web.Contents στη GetNextLink συνάρτηση για εξαγωγή της διεύθυνσης URL της επόμενης σελίδας και την meta ορίζει στην εγγραφή του πίνακα που επιστρέφεται (σελίδα δεδομένων).

Αυτή η υλοποίηση είναι μια ελαφρώς τροποποιημένη έκδοση της TripPin.Feed κλήσης από τα προηγούμενα προγράμματα εκμάθησης.

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

Η GetNextLink συνάρτηση απλώς ελέγχει το σώμα της απόκρισης για ένα @odata.nextLink πεδίο και επιστρέφει την τιμή του.

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

Συνδυάστε τα όλα

Το τελικό βήμα για την υλοποίηση της λογικής σελιδοποίησης είναι η ενημέρωση TripPin.Feed για χρήση των νέων συναρτήσεων. Προς το παρόν, απλώς καλείτε GetAllPagesByNextLinkτο , αλλά σε επόμενα προγράμματα εκμάθησης θα προσθέτετε νέες δυνατότητες (όπως επιβολή σχήματος και λογική παραμέτρων ερωτήματος).

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

Εάν εκτελέσετε ξανά το ίδιο ερώτημα δοκιμής από νωρίτερα στην εκμάθηση, θα πρέπει τώρα να δείτε το πρόγραμμα ανάγνωσης σελίδας σε δράση. Θα πρέπει επίσης να δείτε ότι έχετε 24 γραμμές στην απόκριση αντί για οκτώ.

QueryWithPaging.

Εάν κοιτάξετε τις αιτήσεις στο fiddler, θα πρέπει τώρα να βλέπετε ξεχωριστές αιτήσεις για κάθε σελίδα δεδομένων.

Fiddler.

Σημείωμα

Θα παρατηρήσετε διπλότυπες αιτήσεις για την πρώτη σελίδα δεδομένων από την υπηρεσία, το οποίο δεν είναι ιδανικό. Η επιπλέον αίτηση είναι αποτέλεσμα της συμπεριφοράς ελέγχου σχήματος του μηχανισμού M. Αγνοήστε αυτό το πρόβλημα προς το παρόν και επιλύστε το στο επόμενο πρόγραμμα εκμάθησης, όπου θα εφαρμόσετε ένα ρητό σχήμα.

Συμπέρασμα

Αυτό το μάθημα σάς έδειξε πώς να υλοποιήσετε υποστήριξη σελιδοποίησης για ένα Rest API. Ενώ η λογική πιθανότατα θα διαφέρει μεταξύ των API, το μοτίβο που ορίζεται εδώ θα πρέπει να είναι επαναχρησιμοποιήσιμο με μικρές τροποποιήσεις.

Στο επόμενο μάθημα, θα δείτε πώς μπορείτε να εφαρμόσετε ένα ρητό σχήμα στα δεδομένα σας, υπερβείτε τους απλούς text και number τους τύπους δεδομένων που λαμβάνετε από Json.Documentτο .

Επόμενα βήματα

TripPin Part 6 - Σχήμα