Bagikan melalui


TripPin bagian 4 - Jalur sumber data

Tutorial multi-bagian ini mencakup pembuatan ekstensi sumber data baru untuk Power Query. Tutorial ini dimaksudkan untuk dilakukan secara berurutan—setiap pelajaran dibangun pada konektor yang dibuat dalam pelajaran sebelumnya, secara bertahap menambahkan kemampuan baru ke konektor Anda.

Dalam pelajaran ini, Anda akan:

  • Menyederhanakan logika koneksi untuk konektor Anda
  • Meningkatkan pengalaman tabel navigasi

Pelajaran ini menyederhanakan konektor yang dibangun dalam pelajaran sebelumnya dengan menghapus parameter fungsi yang diperlukan, dan meningkatkan pengalaman pengguna dengan pindah ke tabel navigasi yang dihasilkan secara dinamis.

Untuk penjelasan mendalam tentang bagaimana kredensial diidentifikasi, lihat bagian Jalur Sumber Data dari Menangani Autentikasi.

Jalur sumber data

Saat memanggil fungsi sumber data, mesin M mengidentifikasi kredensial mana yang akan digunakan selama evaluasi dengan melakukan pencarian berdasarkan nilai Jenis Sumber Data dan Jalur Sumber Data.

Dalam pelajaran sebelumnya, Anda berbagi dua fungsi sumber data, keduanya dengan satu parameter Uri.Type.

[DataSource.Kind="TripPin"]
shared TripPin.Feed = Value.ReplaceType(TripPinImpl, type function (url as Uri.Type) as any);

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents =  Value.ReplaceType(TripPinNavTable, type function (url as Uri.Type) as any);

Pertama kali Anda menjalankan kueri yang menggunakan salah satu fungsi, Anda akan menerima perintah kredensial dengan drop-down yang memungkinkan Anda memilih jalur dan jenis autentikasi.

Kredensial dengan Jalur.

Jika Anda menjalankan kueri yang sama lagi, dengan parameter yang sama, mesin M dapat menemukan kredensial yang di-cache, dan tidak ada permintaan kredensial yang ditampilkan. Jika Anda mengubah url argumen ke fungsi Anda sehingga jalur dasar tidak lagi cocok, perintah kredensial baru ditampilkan untuk jalur baru.

Anda dapat melihat kredensial yang di-cache pada tabel Kredensial di jendela Output Kueri M.

Tab Kredensial.

Bergantung pada jenis perubahan, memodifikasi parameter fungsi Anda kemungkinan akan mengakibatkan kesalahan kredensial.

Menyederhanakan konektor

Sekarang Anda akan menyederhanakan konektor dengan menghapus parameter untuk fungsi sumber data Anda (TripPin.Contents). Anda juga akan menghapus shared kualifikasi untuk TripPin.Feed, dan membiarkannya sebagai fungsi internal saja.

Salah satu filosofi desain Power Query adalah menjaga dialog sumber data awal sesingkat mungkin. Jika memungkinkan, Anda harus memberi pengguna pilihan di tingkat Navigator, bukan pada dialog koneksi. Jika nilai yang disediakan pengguna dapat ditentukan secara terprogram, pertimbangkan untuk menambahkannya sebagai tingkat atas tabel navigasi Anda daripada parameter fungsi.

Misalnya, saat menyambungkan ke database relasional, Anda mungkin memerlukan nama server, database, dan tabel. Setelah Anda mengetahui server yang akan disambungkan, dan kredensial telah disediakan, Anda dapat menggunakan API database untuk mengambil daftar database, dan daftar tabel yang terkandung dalam setiap database. Dalam hal ini, untuk menjaga dialog koneksi awal Anda sesingkat mungkin, hanya nama server yang harus menjadi parameter yang diperlukan—Database dan Table akan menjadi tingkat tabel navigasi Anda.

Karena layanan TripPin memiliki titik akhir URL tetap, Anda tidak perlu meminta nilai apa pun kepada pengguna. Anda akan menghapus parameter url dari fungsi Anda, dan menentukan variabel BaseUrl di konektor Anda.

BaseUrl = "https://services.odata.org/v4/TripPinService/";

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents = () => TripPinNavTable(BaseUrl) as table;

Anda akan menyimpan TripPin.Feed fungsi, tetapi tidak lagi membuatnya dibagikan, tidak lagi mengaitkannya dengan Jenis Sumber Data, dan menyederhanakan deklarasinya. Mulai saat ini, Anda hanya akan menggunakannya secara internal dalam dokumen bagian ini.

TripPin.Feed = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source)
    in
        json;

Jika Anda memperbarui TripPin.Contents() panggilan dalam TripPin.query.pq file dan menjalankannya di Visual Studio Code, Anda akan melihat perintah kredensial baru. Perhatikan bahwa sekarang ada satu nilai Jalur Sumber Data—TripPin.

Kredensial tanpa jalur.

Meningkatkan tabel navigasi

Dalam tutorial pertama Anda menggunakan fungsi bawaan OData untuk terhubung ke layanan TripPin. Ini memberi Anda tabel navigasi yang terlihat bagus, berdasarkan dokumen layanan TripPin, tanpa kode lagi di sisi Anda. Fungsi OData.Feed secara otomatis melakukan kerja keras untuk Anda. Karena Anda "kasar" dengan menggunakan Web.Contents daripada OData.Feed, Anda harus membuat ulang tabel navigasi ini sendiri.

OData Navigator.

Anda akan membuat perubahan berikut:

  1. Tentukan daftar item yang akan diperlihatkan dalam tabel navigasi Anda
  2. Lakukan dengan fungsi spesifik entitas (GetAirlineTables dan GetAirportsTable)

Membuat tabel navigasi dari daftar

Anda akan mencantumkan entitas yang ingin Anda ekspos di tabel navigasi, dan membuat URL yang sesuai untuk mengaksesnya. Karena semua entitas berada di bawah jalur akar yang sama, Anda akan dapat membangun URL ini secara dinamis.

Untuk menyederhanakan contoh, Anda hanya akan mengekspos tiga set entitas (Maskapai, Bandara, Orang), yang akan diekspos sebagai Tabel dalam M, dan melewati singleton (Saya) yang akan diekspos sebagai Rekaman. Anda akan melewati penambahan fungsi hingga pelajaran selanjutnya.

RootEntities = {
    "Airlines",
    "Airports",
    "People"
};

Anda kemudian memperbarui fungsi Anda TripPinNavTable untuk membangun tabel kolom pada satu waktu. Kolom [Data] untuk setiap entitas diambil dengan memanggil TripPin.Feed dengan URL lengkap ke entitas.

TripPinNavTable = (url as text) as table =>
    let
        entitiesAsTable = Table.FromList(RootEntities, Splitter.SplitByNothing()),
        rename = Table.RenameColumns(entitiesAsTable, {{"Column1", "Name"}}),
        // Add Data as a calculated column
        withData = Table.AddColumn(rename, "Data", each TripPin.Feed(Uri.Combine(url, [Name])), Uri.Type),
        // Add ItemKind and ItemName as fixed text values
        withItemKind = Table.AddColumn(withData, "ItemKind", each "Table", type text),
        withItemName = Table.AddColumn(withItemKind, "ItemName", each "Table", type text),
        // Indicate that the node should not be expandable
        withIsLeaf = Table.AddColumn(withItemName, "IsLeaf", each true, type logical),
        // Generate the nav table
        navTable = Table.ToNavigationTable(withIsLeaf, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
    in
        navTable;

Saat membangun jalur URL secara dinamis, pastikan Anda jelas di mana garis miring (/) Anda berada! Perhatikan bahwa Uri.Combine menggunakan aturan berikut saat menggabungkan jalur:

  • relativeUri Ketika parameter dimulai dengan /, parameter akan menggantikan seluruh jalur baseUri parameter
  • relativeUri Jika parameter tidak dimulai dengan / dan baseUri diakhir dengan /, jalur ditambahkan
  • relativeUri Jika parameter tidak dimulai dengan / dan baseUri tidak berakhir dengan /, segmen terakhir jalur diganti

Gambar berikut menunjukkan contoh ini:

Contoh Uri.Combine.

Menghapus fungsi spesifik entitas

Untuk mempermudah pemeliharaan konektor, Anda akan menghapus fungsi pemformatan khusus entitas yang Anda gunakan dalam pelajaran sebelumnya—GetAirlineTables dan GetAirportsTable. Sebagai gantinya, Anda akan memperbarui TripPin.Feed untuk memproses respons JSON dengan cara yang akan berfungsi untuk semua entitas Anda. Secara khusus, Anda mengambil value bidang payload OData JSON yang dikembalikan, dan mengonversinya dari daftar rekaman menjadi tabel.

TripPin.Feed = (url as text) =>
    let
        source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
        json = Json.Document(source),
        // The response is a JSON record - the data we want is a list of records in the "value" field
        value = json[value],
        asTable = Table.FromList(value, Splitter.SplitByNothing()),
        // expand all columns from the record
        fields = Record.FieldNames(Table.FirstValue(asTable, [Empty = null])),
        expandAll = Table.ExpandRecordColumn(asTable, "Column1", fields)
    in
        expandAll;

Catatan

Kerugian menggunakan pendekatan generik untuk memproses entitas Anda adalah Anda kehilangan informasi pemformatan dan jenis yang bagus untuk entitas Anda. Bagian selanjutnya dalam tutorial ini menunjukkan cara menerapkan skema pada panggilan REST API.

Kesimpulan

Dalam tutorial ini, Anda membersihkan dan menyederhanakan konektor Anda dengan memperbaiki nilai Jalur Sumber Data Anda, dan berpindah ke format yang lebih fleksibel untuk tabel navigasi Anda. Setelah menyelesaikan langkah-langkah ini (atau menggunakan kode sampel di direktori ini), TripPin.Contents fungsi mengembalikan tabel navigasi di Power BI Desktop.

Navigator.

Langkah berikutnya

TripPin Bagian 5 - Halaman