TripPin μέρος 2 - Σύνδεση δεδομένων για μια υπηρεσία REST
Αυτή η εκμάθηση πολλαπλών τμημάτων καλύπτει τη δημιουργία μιας νέας επέκτασης προέλευσης δεδομένων για το Power Query. Το εκπαιδευτικό βοήθημα προορίζεται να γίνει διαδοχικά. Κάθε μάθημα βασίζεται στη σύνδεση που δημιουργήθηκε σε προηγούμενα μαθήματα, προσθέτοντας σταδιακά νέες δυνατότητες στη σύνδεσή σας.
Σε αυτό το μάθημα, θα κάνετε τα εξής:
- Δημιουργήστε μια βασική συνάρτηση που καλεί ένα REST API χρησιμοποιώντας το Web.Contents
- Μάθετε πώς μπορείτε να ορίσετε κεφαλίδες αιτήσεων και να επεξεργαστείτε μια απόκριση JSON
- Χρήση του Power BI Desktop για τη διευθέτηση της απόκρισης σε μια μορφή φιλική προς τον χρήστη
Αυτό το μάθημα μετατρέπει τη σύνδεση που βασίζεται σε OData για την υπηρεσία TripPin (που δημιουργήθηκε στο προηγούμενο μάθημα) σε μια σύνδεση που μοιάζει με κάτι που θα δημιουργήσετε για οποιοδήποτε RESTful API. Το OData είναι ένα RESTful API, αλλά ένα με ένα σταθερό σύνολο συμβάσεων. Το πλεονέκτημα του OData είναι ότι παρέχει ένα σχήμα, ένα πρωτόκολλο ανάκτησης δεδομένων και μια τυπική γλώσσα ερωτημάτων. Η αφαίρεση της χρήσης του OData.Feed θα απαιτήσει να δημιουργήσουμε αυτές τις δυνατότητες στη σύνδεση μόνοι μας.
Ανακεφαλαίωση της σύνδεσης OData
Προτού καταργήσετε τις συναρτήσεις OData από τη σύνδεσή σας, ας εξετάσουμε γρήγορα τι κάνει (κυρίως στο παρασκήνιο) για την ανάκτηση δεδομένων από την υπηρεσία.
Ανοίξτε το έργο επέκτασης TripPin από το Μέρος 1 στο Visual Studio Code. Ανοίξτε το αρχείο Ερωτήματος και επικολλήστε το στο ακόλουθο ερώτημα:
TripPin.Feed("https://services.odata.org/v4/TripPinService/Me")
Ανοίξτε το Fiddler και, στη συνέχεια, αξιολογήστε το τρέχον αρχείο Power Query στο Visual Studio Code.
Στο Fiddler, υπάρχουν τρεις αιτήσεις στον διακομιστή:
/Me
— η πραγματική διεύθυνση URL που ζητάτε./$metadata
— μια κλήση που πραγματοποιείται αυτόματα από τη συνάρτηση για τον προσδιορισμό τουOData.Feed
σχήματος και τον τύπο πληροφοριών σχετικά με την απόκριση./Me/BestFriend
— ένα από τα πεδία που (με ανυπομονησία) ανατίθενται όταν καταχωρήσετε το singleton /Me. Σε αυτή την περίπτωση, η κλήση είχε ως αποτέλεσμα μια204 No Content
κατάσταση.
Η αξιολόγηση M είναι κυρίως αργή. Στις περισσότερες περιπτώσεις, οι τιμές δεδομένων ανακτώνται/αντλούνται μόνο όταν χρειάζονται. Υπάρχουν σενάρια (όπως η περίπτωση /Me/BestFriend) όπου μια τιμή αντλείται με ανυπομονησία. Αυτό τείνει να συμβαίνει όταν απαιτούνται πληροφορίες τύπου για ένα μέλος και ο μηχανισμός δεν έχει άλλο τρόπο για να προσδιορίσει τον τύπο από το να ανακτήσει την τιμή και να την ελέγξει. Κάνοντας τα πράγματα αργή (δηλαδή, αποφεύγοντας τις πρόθυμες έλξης) είναι μία από τις βασικές πτυχές για την εκτέλεση μιας σύνδεσης M.
Σημειώστε τις κεφαλίδες αίτησης που στάλθηκαν μαζί με τις αιτήσεις και τη μορφή JSON της απόκρισης της αίτησης /Me.
{
"@odata.context": "https://services.odata.org/v4/TripPinService/$metadata#Me",
"UserName": "aprilcline",
"FirstName": "April",
"LastName": "Cline",
"MiddleName": null,
"Gender": "Female",
"Age": null,
"Emails": [ "April@example.com", "April@contoso.com" ],
"FavoriteFeature": "Feature1",
"Features": [ ],
"AddressInfo": [
{
"Address": "P.O. Box 555",
"City": {
"Name": "Lander",
"CountryRegion": "United States",
"Region": "WY"
}
}
],
"HomeAddress": null
}
Όταν το ερώτημα ολοκληρώσει την αξιολόγηση, το παράθυρο αποτελεσμάτων PQTest θα πρέπει να εμφανίζει την τιμή Εγγραφή για το μονότονο Me.
Εάν συγκρίνετε τα πεδία στο παράθυρο εξόδου με τα πεδία που επιστρέφονται στην μη επεξεργασμένη απόκριση JSON, παρατηρείτε ασυμφωνία. Το αποτέλεσμα του ερωτήματος έχει άλλα πεδία (Friends
, Trips
, GetFriendsTrips
) που δεν εμφανίζονται πουθενά στην απόκριση JSON. Η συνάρτηση OData.Feed προσαρτά αυτόματα αυτά τα πεδία στην εγγραφή με βάση το σχήμα που επιστρέφεται από $metadata. Αυτό είναι ένα καλό παράδειγμα για το πώς μια σύνδεση μπορεί να αυξήσει ή/και να μορφοποιήσει εκ νέου την απόκριση από την υπηρεσία για την παροχή μιας καλύτερης εμπειρίας χρήστη.
Δημιουργία βασικής σύνδεσης REST
Τώρα θα προσθέσετε μια νέα συνάρτηση που έχει εξαχθεί στη σύνδεσή σας που καλεί το Web.Contents.
Για να είναι δυνατή η πραγματοποίηση επιτυχημένων αιτήσεων web στην υπηρεσία OData, ωστόσο, θα πρέπει να ορίσετε ορισμένες τυπικές κεφαλίδες OData. Αυτό θα το κάνετε ορίζοντας ένα κοινό σύνολο κεφαλίδων ως νέα μεταβλητή στη σύνδεσή σας:
DefaultRequestHeaders = [
#"Accept" = "application/json;odata.metadata=minimal", // column name and values only
#"OData-MaxVersion" = "4.0" // we only support v4
];
Αλλάζετε την υλοποίηση της συνάστασής σας TripPin.Feed
έτσι ώστε, αντί να χρησιμοποιείτε OData.Feed
το , να χρησιμοποιεί το Web.Contents για να υποβάλει μια αίτηση web και να αναλύει το αποτέλεσμα ως έγγραφο JSON.
TripPinImpl = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Μην ξεχάσετε να δημιουργήσετε τη σύνδεσή σας τώρα που έχετε κάνει αλλαγές στο αρχείο σύνδεσης. Στη συνέχεια, μπορείτε να αξιολογήσετε το αρχείο ερωτήματος (TripPin.query.pq). Το αποτέλεσμα της εγγραφής /Me τώρα μοιάζει με το ανεπεξέργαστο JSON που είδατε στην αίτηση Fiddler.
Εάν παρακολουθείτε το Fiddler κατά την εκτέλεση της νέας συνάρτησης, θα παρατηρήσετε επίσης ότι η αξιολόγηση κάνει τώρα μία αίτηση web αντί για τρεις. Συγχαρητήρια. Έχετε επιτύχει αύξηση των επιδόσεων κατά 300%! Τώρα έχετε χάσει όλες τις πληροφορίες τύπου και σχήματος, αλλά δεν χρειάζεται να εστιάσετε σε αυτό το τμήμα ακόμα.
Ενημερώστε το ερώτημά σας για να αποκτήσετε πρόσβαση σε ορισμένες από τις οντότητες/πίνακες TripPin, όπως:
https://services.odata.org/v4/TripPinService/Airlines
https://services.odata.org/v4/TripPinService/Airports
https://services.odata.org/v4/TripPinService/Me/Trips
Θα παρατηρήσετε ότι οι διαδρομές που χρησιμοποιήθηκαν για την επιστροφή πινάκων με καλή μορφοποίηση επιστρέφουν τώρα ένα πεδίο "τιμής" ανώτατου επιπέδου με ενσωματωμένο [Λίστα]. Θα χρειαστεί να κάνετε ορισμένους μετασχηματισμούς με βάση το αποτέλεσμα, ώστε να είναι δυνατή η χρήση του για σενάρια κατανάλωσης τελικού χρήστη.
Μετασχηματισμοί σύνταξης στο Power Query
Ενώ είναι δυνατό να συντάξετε τους μετασχηματισμούς M με το χέρι, οι περισσότεροι χρήστες προτιμούν να χρησιμοποιούν το Power Query για να διαμορφώσουν τα δεδομένα τους. Θα ανοίξετε την επέκτασή σας στο Power BI Desktop και θα τη χρησιμοποιήσετε για να σχεδιάσετε ερωτήματα για να μετατρέψετε την έξοδο σε μια πιο φιλική προς τον χρήστη μορφή. Επαναδομήστε τη λύση σας, αντιγράψτε το νέο αρχείο επέκτασης στον κατάλογο Προσαρμοσμένα δεδομένα Σύνδεση ors και επανεκτελέστε το Power BI Desktop.
Ξεκινήστε ένα νέο Κενό ερώτημα και επικολλήστε τα παρακάτω στη γραμμή τύπων:
= TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines")
Φροντίστε να συμπεριλάβετε το σύμβολο = .
Χειριστείτε την έξοδο μέχρι να μοιάζει με την αρχική τροφοδοσία OData, έναν πίνακα με δύο στήλες: AirlineCode και Name.
Το ερώτημα που προκύπτει θα πρέπει να μοιάζει κάπως έτσι:
let
Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines"),
value = Source[value],
toTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
expand = Table.ExpandRecordColumn(toTable, "Column1", {"AirlineCode", "Name"}, {"AirlineCode", "Name"})
in
expand
Δώστε ένα όνομα στο ερώτημα ("Airlines").
Δημιουργήστε ένα νέο κενό ερώτημα. Αυτή τη φορά, χρησιμοποιήστε τη TripPin.Feed
συνάρτηση για να αποκτήσετε πρόσβαση στην οντότητα /Airports. Εφαρμόστε μετασχηματισμούς μέχρι να λάβετε κάτι παρόμοιο με τον κοινόχρηστο χώρο που εμφανίζεται παρακάτω. Μπορείτε επίσης να βρείτε το ερώτημα αντιστοίχισης παρακάτω. Δώστε σε αυτό το ερώτημα ένα όνομα ("Αεροδρόμια").
let
Source = TripPin.Feed("https://services.odata.org/v4/TripPinService/Airports"),
value = Source[value],
#"Converted to Table" = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"Name", "IcaoCode", "IataCode", "Location"}, {"Name", "IcaoCode", "IataCode", "Location"}),
#"Expanded Location" = Table.ExpandRecordColumn(#"Expanded Column1", "Location", {"Address", "Loc", "City"}, {"Address", "Loc", "City"}),
#"Expanded City" = Table.ExpandRecordColumn(#"Expanded Location", "City", {"Name", "CountryRegion", "Region"}, {"Name.1", "CountryRegion", "Region"}),
#"Renamed Columns" = Table.RenameColumns(#"Expanded City",{{"Name.1", "City"}}),
#"Expanded Loc" = Table.ExpandRecordColumn(#"Renamed Columns", "Loc", {"coordinates"}, {"coordinates"}),
#"Added Custom" = Table.AddColumn(#"Expanded Loc", "Latitude", each [coordinates]{1}),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Longitude", each [coordinates]{0}),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"coordinates"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Columns",{{"Name", type text}, {"IcaoCode", type text}, {"IataCode", type text}, {"Address", type text}, {"City", type text}, {"CountryRegion", type text}, {"Region", type text}, {"Latitude", type number}, {"Longitude", type number}})
in
#"Changed Type"
Μπορείτε να επαναλάβετε αυτήν τη διαδικασία για περισσότερες διαδρομές στην υπηρεσία. Όταν είστε έτοιμοι, προχωρήστε στο επόμενο βήμα δημιουργίας ενός (εικονικού) πίνακα περιήγησης.
Προσομοίωση πίνακα περιήγησης
Τώρα θα δημιουργήσετε έναν πίνακα (χρησιμοποιώντας κώδικα M) που παρουσιάζει τις όμορφα μορφοποιημένες οντότητές σας TripPin.
Ξεκινήστε ένα νέο κενό ερώτημα και εμφανίσετε το Προηγμένο πρόγραμμα επεξεργασίας.
Επικολλήστε το παρακάτω ερώτημα:
let
source = #table({"Name", "Data"}, {
{ "Airlines", Airlines },
{ "Airports", Airports }
})
in
source
Εάν δεν έχετε ορίσει τη ρύθμιση Επίπεδα προστασίας προσωπικών δεδομένων σε "Να παραβλέπετε πάντα τις ρυθμίσεις επιπέδου προστασίας προσωπικών δεδομένων" (γνωστός και ως "Γρήγορος συνδυασμός"), θα δείτε μια ερώτηση προστασίας προσωπικών δεδομένων.
Εμφανίζονται προτροπές προστασίας προσωπικών δεδομένων όταν συνδυάζετε δεδομένα από πολλές προελεύσεις και δεν έχετε καθορίσει ακόμα επίπεδο προστασίας προσωπικών δεδομένων για μία ή περισσότερες προελεύσεις. Επιλέξτε το κουμπί Συνέχεια και ορίστε το επίπεδο προστασίας προσωπικών δεδομένων της κορυφαίας προέλευσης σε Δημόσιο.
Επιλέξτε Αποθήκευση και θα εμφανιστεί ο πίνακάς σας. Παρόλο που αυτός δεν είναι ακόμα ένας πίνακας περιήγησης, παρέχει τις βασικές λειτουργίες που χρειάζεστε για να τον μετατρέψετε σε ένα σε επόμενο μάθημα.
Οι έλεγχοι συνδυασμού δεδομένων δεν πραγματοποιούνται κατά την πρόσβαση σε πολλές προελεύσεις δεδομένων μέσα από μια επέκταση. Δεδομένου ότι όλες οι κλήσεις προέλευσης δεδομένων που γίνονται μέσα από την επέκταση λαμβάνουν το ίδιο περιβάλλον εξουσιοδότησης, θεωρείται ότι είναι "ασφαλείς" να συνδυαστούν. Η επέκτασή σας θα αντιμετωπίζεται πάντα ως μία προέλευση δεδομένων σε ό,τι αφορά τους κανόνες συνδυασμού δεδομένων. Οι χρήστες θα εξακολουθήσουν να λαμβάνουν τις τακτικές προτροπές προστασίας προσωπικών δεδομένων κατά τον συνδυασμό της προέλευσής σας με άλλες προελεύσεις M.
Εάν εκτελέσετε το Fiddler και επιλέξετε το κουμπί Ανανέωση προεπισκόπησης στο πρόγραμμα επεξεργασίας Power Query, σημειώστε τις ξεχωριστές αιτήσεις Web για κάθε στοιχείο στον πίνακα περιήγησης. Αυτό υποδεικνύει ότι πραγματοποιείται μια γρήγορη αξιολόγηση, η οποία δεν είναι ιδανική όταν δημιουργείτε πίνακες περιήγησης με πολλά στοιχεία. Τα επόμενα μαθήματα δείχνουν πώς μπορείτε να δημιουργήσετε έναν κατάλληλο πίνακα περιήγησης που υποστηρίζει αργή αξιολόγηση.
Συμπέρασμα
Αυτό το μάθημα σάς έδειξε πώς να δημιουργήσετε μια απλή σύνδεση για μια υπηρεσία REST. Σε αυτή την περίπτωση, μετατρέψατε μια υπάρχουσα επέκταση OData σε μια τυπική επέκταση REST (χρησιμοποιώντας web.Contents), αλλά οι ίδιες έννοιες ισχύουν εάν δημιουργούσατε μια νέα επέκταση από την αρχή.
Στο επόμενο μάθημα, θα λάβετε τα ερωτήματα που δημιουργήθηκαν σε αυτό το μάθημα χρησιμοποιώντας το Power BI Desktop και θα τα μετατρέψετε σε έναν πραγματικό πίνακα περιήγησης εντός της επέκτασης.