TripPin bölüm 2 - REST hizmeti için veri bağlayıcısı
Bu çok bölümlü öğretici, Power Query için yeni bir veri kaynağı uzantısı oluşturmayı kapsar. Öğreticinin sırayla yapılması amaçlanır; her ders önceki derslerde oluşturulan bağlayıcı üzerinde oluşturulur ve bağlayıcınıza artımlı olarak yeni özellikler ekler.
Bu derste şunları yapacaksınız:
- Web.Contents kullanarak REST API'ye çağrıda bulunur temel bir işlev oluşturma
- İstek üst bilgilerini ayarlamayı ve JSON yanıtını işlemeyi öğrenin
- Yanıtı kullanıcı dostu bir biçimde düzenlemek için Power BI Desktop'ı kullanma
Bu ders, TripPin hizmeti için OData tabanlı bağlayıcıyı (önceki derste oluşturulmuş) herhangi bir RESTful API için oluşturacağınız bir şeye benzeyen bir bağlayıcıya dönüştürür. OData bir RESTful API'dir, ancak sabit bir kural kümesine sahip bir API'dir. OData'nın avantajı bir şema, veri alma protokolü ve standart sorgu dili sağlamasıdır. OData.Feed'in kullanımını ortadan kaldırmamız için bu özellikleri bağlayıcıya kendimiz eklememiz gerekir.
OData bağlayıcısının özeti
Bağlayıcınızdan OData işlevlerini kaldırmadan önce hizmetten veri almak için şu anda ne yaptığını (çoğunlukla arka planda) hızlı bir şekilde gözden geçirelim.
Visual Studio Code'da Bölüm 1'den TripPin uzantısı projesini açın. Sorgu dosyasını açın ve aşağıdaki sorguya yapıştırın:
TripPin.Feed("https://services.odata.org/v4/TripPinService/Me")
Fiddler'ı açın ve geçerli Power Query dosyasını Visual Studio Code'da değerlendirin.
Fiddler'da sunucuya yönelik üç istek vardır:
/Me
— istediğiniz gerçek URL./$metadata
—şemayıOData.Feed
belirlemek ve yanıt hakkındaki bilgileri yazmak için işlev tarafından otomatik olarak yapılan bir çağrı./Me/BestFriend
—/Me tekilini listelediğinizde (hevesle) çekilen alanlardan biri. Bu durumda çağrı bir204 No Content
durumla sonuçlandı.
M değerlendirmesi çoğunlukla tembeldir. Çoğu durumda veri değerleri yalnızca ihtiyaç duyulduğunda alınır/çekilir. Bir değerin hevesle çekildiği senaryolar (/Me/BestFriend örneği gibi) vardır. Bu durum, bir üye için tür bilgileri gerektiğinde ve altyapının türü belirlemek için değeri alıp incelemekten başka bir yolu olmadığında ortaya çıkar. İşleri tembel hale getirmek (yani, istekli çekmelerden kaçınmak), M bağlayıcısının performans göstermesini sağlamanın önemli yönlerinden biridir.
İsteklerle birlikte gönderilen istek üst bilgilerini ve /Me isteğinin yanıtının JSON biçimini not edin.
{
"@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
}
Sorgu değerlendirmeyi tamamladığında, PQTest sonuç penceresinde Me singleton için Kayıt değeri gösterilmelidir.
Çıkış penceresindeki alanları ham JSON yanıtında döndürülen alanlarla karşılaştırırsanız, bir uyuşmazlık fark edeceksiniz. Sorgu sonucunun JSON yanıtında hiçbir yerde görünmeyen başka alanları (Friends
, Trips
, GetFriendsTrips
) vardır. OData.Feed işlevi, $metadata tarafından döndürülen şemaya göre bu alanları otomatik olarak kayda ekledi. Bu, daha iyi bir kullanıcı deneyimi sağlamak için bağlayıcının hizmetten gelen yanıtı nasıl artırabileceğine ve/veya yeniden biçimlendirebileceğine ilişkin iyi bir örnektir.
Temel REST bağlayıcısı oluşturma
Şimdi bağlayıcınıza Web.Contents'i çağıran yeni bir dışarı aktarılan işlev ekleyeceksiniz.
Ancak OData hizmetine başarılı web istekleri gönderebilmek için bazı standart OData üst bilgileri ayarlamanız gerekir. Bunu yapmak için bağlayıcınızda ortak bir üst bilgi kümesini yeni bir değişken olarak tanımlayacaksınız:
DefaultRequestHeaders = [
#"Accept" = "application/json;odata.metadata=minimal", // column name and values only
#"OData-MaxVersion" = "4.0" // we only support v4
];
İşlevinizin TripPin.Feed
uygulamasını, web isteğinde bulunmak için Web.Contents kullanarak kullanmak OData.Feed
yerine JSON belgesi olarak ayrıştıracak şekilde değiştirirsiniz.
TripPinImpl = (url as text) =>
let
source = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
json = Json.Document(source)
in
json;
Bağlayıcı dosyasında değişiklik yaptığınıza göre bağlayıcınızı oluşturmayı unutmayın. Ardından sorgu dosyasını (TripPin.query.pq) değerlendirebilirsiniz. /Me kaydının sonucu artık Fiddler isteğinde gördüğünüz ham JSON'a benzer.
Yeni işlevi çalıştırırken Fiddler'ı izlerseniz, değerlendirmenin artık üç yerine tek bir web isteğinde bulunduğunu da fark edersiniz. Tebrikler, %300 performans artışı elde ettiniz! Şimdi tüm tür ve şema bilgilerini kaybettiniz, ancak henüz bu bölüme odaklanmanıza gerek yok.
Aşağıdakiler gibi TripPin Varlık/Tablolarından bazılarına erişmek için sorgunuzu güncelleştirin:
https://services.odata.org/v4/TripPinService/Airlines
https://services.odata.org/v4/TripPinService/Airports
https://services.odata.org/v4/TripPinService/Me/Trips
Eskiden düzgün biçimlendirilmiş tablolar döndürmek için kullanılan yolların artık eklenmiş [List] içeren bir üst düzey "değer" alanı döndürdüğünü fark edeceksiniz. Son kullanıcı tüketimi senaryolarında kullanılabilir hale getirmek için sonuç üzerinde bazı dönüştürmeler yapmanız gerekir.
Power Query'de dönüştürme yazma
M dönüşümlerinizi el ile yazmak mümkün olsa da, çoğu kişi verilerini şekillendirmek için Power Query'yi kullanmayı tercih eder. Uzantınızı Power BI Desktop'ta açacak ve çıkışı daha kullanıcı dostu bir biçime dönüştürecek sorgular tasarlamak için kullanacaksınız. Çözümünüzü yeniden oluşturun, yeni uzantı dosyasını Özel Veri Bağlan ors dizininize kopyalayın ve Power BI Desktop'ı yeniden başlatın.
Yeni bir Boş Sorgu başlatın ve aşağıdakini formül çubuğuna yapıştırın:
= TripPin.Feed("https://services.odata.org/v4/TripPinService/Airlines")
= işaretini eklediğinizden emin olun.
Çıkışı, iki sütunlu bir tablo olan özgün OData akışı gibi görünene kadar işleyin: AirlineCode ve Name.
Sonuçta elde edilen sorgu şuna benzer olmalıdır:
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
Sorguya bir ad verin ("Havayolları").
Yeni bir Boş Sorgu oluşturun. Bu kez işlevini kullanarak TripPin.Feed
/Airports varlığına erişin. Aşağıda gösterilen paylaşıma benzer bir şey elde edene kadar dönüşümleri uygulayın. Eşleşen sorgu aşağıda da bulunabilir; bu sorguya da bir ad verin ("Havaalanları").
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"
Hizmet altında daha fazla yol için bu işlemi yineleyebilirsiniz. Hazır olduğunuzda, bir sonraki (sahte) gezinti tablosu oluşturma adımına geçin.
Gezinti tablosu benzetimi
Şimdi güzel biçimlendirilmiş TripPin varlıklarınızı sunan bir tablo (M kodu kullanarak) oluşturacaksınız.
Yeni bir Boş Sorgu başlatın ve Gelişmiş Düzenleyici açın.
Aşağıdaki sorguyu yapıştırın:
let
source = #table({"Name", "Data"}, {
{ "Airlines", Airlines },
{ "Airports", Airports }
})
in
source
Gizlilik Düzeyleri ayarınızı "Gizlilik düzeyi ayarlarını her zaman yoksay" ("Hızlı Birleştirme" olarak da bilinir) olarak ayarlamadıysanız bir gizlilik istemi görürsünüz.
Birden çok kaynaktan verileri birleştirdiğinizde ve bir veya daha fazla kaynak için henüz bir gizlilik düzeyi belirtmediğinizde gizlilik istemleri görüntülenir. Devam düğmesini seçin ve üst kaynağın gizlilik düzeyini Genel olarak ayarlayın.
Kaydet'i seçtiğinizde tablonuz görüntülenir. Bu henüz bir gezinti tablosu olmasa da, sonraki bir derste bunu bir gezinti tablosuna dönüştürmek için ihtiyacınız olan temel işlevselliği sağlar.
Bir uzantıdan birden çok veri kaynağına erişilirken veri bileşimi denetimleri gerçekleşmez. Uzantı içinden yapılan tüm veri kaynağı çağrıları aynı yetkilendirme bağlamını devraldığından, bunların birleştirildiği "güvenli" olduğu varsayılır. Veri bileşimi kuralları söz konusu olduğunda uzantınız her zaman tek bir veri kaynağı olarak değerlendirilir. Kullanıcılar, kaynağınızı diğer M kaynaklarıyla birleştirirken normal gizlilik istemlerini almaya devam eder.
Fiddler'ı çalıştırır ve Sorgu Düzenleyicisi Yenile Önizleme düğmesini seçerseniz, gezinti tablonuzdaki her öğe için ayrı web isteklerini not edin. Bu, çok sayıda öğe içeren gezinti tabloları oluştururken ideal olmayan istekli bir değerlendirmenin gerçekleştiğini gösterir. Sonraki dersler, gecikmeli değerlendirmeyi destekleyen uygun bir gezinti tablosunun nasıl derlendiğini gösterir.
Sonuç
Bu ders size REST hizmeti için basit bir bağlayıcı oluşturmayı gösterdi. Bu durumda, mevcut bir OData uzantısını standart bir REST uzantısına (Web.Contents kullanarak) dönüştürdün, ancak sıfırdan yeni bir uzantı oluşturuyorsanız aynı kavramlar geçerli olur.
Sonraki derste Power BI Desktop kullanarak bu derste oluşturulan sorguları alacak ve uzantı içinde gerçek bir gezinti tablosuna dönüştüreceksiniz.