パート4の TripPin データソースのパスTripPin Part 4 - Data Source Paths

このマルチパートチュートリアルでは、Power Query 用の新しいデータソース拡張機能の作成について説明します。This multi-part tutorial covers the creation of a new data source extension for Power Query. このチュートリアルは、 — 前のレッスンで作成したコネクタに対して各レッスンがビルドされ、コネクタに新しい機能が追加されていくことを目的としています。The tutorial is meant to be done sequentially—each lesson builds on the connector created in previous lessons, incrementally adding new capabilities to your connector.

このレッスンでは、次のことを行います。In this lesson, you will:

  • コネクタの接続ロジックを簡略化するSimplify the connection logic for your connector
  • ナビゲーションテーブルのエクスペリエンスを向上させるImprove the navigation table experience

このレッスンでは、 前のレッスン で作成したコネクタを単純化し、必要な関数パラメーターを削除し、動的に生成されたナビゲーションテーブルに移動してユーザーエクスペリエンスを向上させます。This lesson simplifies the connector built in the previous lesson by removing its required function parameters, and improving the user experience by moving to a dynamically generated navigation table.

資格情報を識別する方法の詳細については、「認証の処理」の「データソースのパス」セクションを参照してください。For an in-depth explanation of how credentials are identified, see the Data Source Paths section of Handling Authentication.

データソースパスData Source Paths

データソース 関数を呼び出すときに、M エンジンは、 データソースの種類データソースパス の値に基づいて参照を行うことによって、評価中に使用する資格情報を識別します。When invoking a data source function, the M engine identifies which credentials to use during an evaluation by doing a lookup based on the Data Source Kind and Data Source Path values.

前の レッスン では、単一の Uri. Type パラメーターを使用して、2つのデータソース関数を共有しています。In the previous lesson you shared two data source functions, both with a single Uri.Type parameter.

[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);

関数のいずれかを使用するクエリを初めて実行すると、ドロップダウンで資格情報プロンプトが表示され、パスと認証の種類を選択できます。The first time you run a query that uses one of the functions, you'll receive a credential prompt with drop downs that lets you select a path and an authentication type.

パスのある資格情報

同じパラメーターを使用して同じクエリを再度実行すると、M エンジンはキャッシュされた資格情報を見つけることができ、資格情報のプロンプトは表示されません。If you run the same query again, with the same parameters, the M engine is able to locate the cached credentials, and no credential prompt is shown. url基本パスが一致しなくなるように関数の引数を変更すると、新しいパスに新しい資格情報プロンプトが表示されます。If you modify the url argument to your function so that the base path no longer matches, a new credential prompt is displayed for the new path.

キャッシュされた資格情報は、[ M クエリ出力 ] ウィンドウの [資格情報] テーブルで確認できます。You can see any cached credentials on the Credentials table in the M Query Output window.

[資格情報] タブ

変更の種類によっては、関数のパラメーターを変更すると、資格情報エラーが発生する可能性があります。Depending on the type of change, modifying the parameters of your function will likely result in a credential error.

コネクタの簡略化Simplifying the Connector

ここでは、データソース関数 () のパラメーターを削除してコネクタを簡略化し TripPin.Contents ます。You'll now simplify your connector by removing the parameters for your data source function (TripPin.Contents). また、 shared の修飾子を削除 TripPin.Feed し、内部専用の関数としてそのまま使用します。You'll also remove the shared qualifier for TripPin.Feed, and leave it as an internal-only function.

Power Query の設計思想の1つは、最初のデータソースダイアログをできるだけ単純なものに保つことです。One of the design philosophies of Power Query is to keep the initial data source dialog as simple as possible. 可能であれば、接続ダイアログではなく、ナビゲーターレベルでユーザーに選択肢を提供する必要があります。If at all possible, you should provide the user with choices at the Navigator level, rather on the connection dialog. ユーザーが指定した値をプログラムによって判断できる場合は、関数パラメーターではなく、ナビゲーションテーブルの最上位レベルとして追加することを検討してください。If a user provided value can be determined programmatically, consider adding it as the top level of your navigation table rather than a function parameter.

たとえば、リレーショナルデータベースに接続する場合、サーバー名、データベース名、およびテーブル名が必要になることがあります。For example, when connecting to a relational database, you might need server, database, and table names. 接続先のサーバーを把握し、資格情報が提供されたら、データベースの API を使用してデータベースの一覧を取得し、各データベース内に含まれるテーブルの一覧を取得することができます。Once you know the server to connect to, and credentials have been provided, you could use the database's API to fetch a list of databases, and a list of tables contained within each database. この場合、初期接続ダイアログをできるだけ単純なものにするには、サーバー名のみを必須パラメーターに — Database し、 Table ナビゲーションテーブルのレベルにします。In this case, to keep your initial connect dialog as simple as possible, only the server name should be a required parameter—Database and Table would be levels of your navigation table.

TripPin サービスには固定の URL エンドポイントがあるため、ユーザーに値の入力を求める必要はありません。Since the TripPin service has a fixed URL endpoint, you don't need to prompt the user for any values. 関数から url パラメーターを削除し、コネクタで BaseUrl 変数を定義します。You'll remove the url parameter from your function, and define a BaseUrl variable in your connector.

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

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

関数を保持しますが、共有することはできず TripPin.Feed 、データソースの種類に関連付けなくなり、宣言が単純化されます。You'll keep the TripPin.Feed function, but no longer make it shared, no longer associate it with a Data Source Kind, and simplify its declaration. ここからは、このセクションの内部でのみ使用します。From this point on, you'll only use it internally within this section document.

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

TripPin.Contents()ファイル内の呼び出しを更新 TripPin.query.pq して Visual Studio で実行すると、新しい資格情報プロンプトが表示されます。If you update the TripPin.Contents() call in your TripPin.query.pq file and run it in Visual Studio, you'll see a new credential prompt. 1つのデータソースパスの値が trippin になっていることに注意 — してください。Note that there is now a single Data Source Path value—TripPin.

パスのない資格情報

ナビゲーションテーブルの改良Improving the Navigation Table

最初の チュートリアル では、組み込み関数を使用して OData trippin サービスに接続しています。In the first tutorial you used the built-in OData functions to connect to the TripPin service. これにより、TripPin サービスドキュメントに基づいて見栄えの良いナビゲーションテーブルが作成されました。コードを追加する必要はありません。This gave you a really nice looking navigation table, based on the TripPin service document, with no additional code on your side. OData関数は自動的にハードな作業を行いました。The OData.Feed function automatically did the hard work for you. ODataではなく、 Web コンテンツを使用して "荒削り" しているため、このナビゲーションテーブルを自分で再作成する必要があります。Since you're "roughing it" by using Web.Contents rather than OData.Feed, you'll need to recreate this navigation table yourself.

OData ナビゲーター

次の変更を行います。You're going to make the following changes:

  1. ナビゲーションテーブルに表示する項目の一覧を定義するDefine a list of items to show in your navigation table
  2. エンティティ固有の関数 ( GetAirlineTables および) を使用 GetAirportsTable するDo away with the entity specific functions (GetAirlineTables and GetAirportsTable)

リストからのナビゲーションテーブルの生成Generating a Navigation Table from a List

ナビゲーションテーブルに公開するエンティティを一覧表示し、それらにアクセスするための適切な URL を作成します。You'll list the entities you want to expose in the navigation table, and build the appropriate URL to access them. すべてのエンティティが同じルートパスにあるため、これらの Url を動的に構築できます。Since all of the entities are under the same root path, you'll be able build these URLs dynamically.

この例を簡略化するために、M でテーブルとして公開される3つのエンティティセット (航空会社、空港、People) のみを公開し、レコードとして公開されるシングルトン (Me) をスキップします。To simplify the example, you'll only expose the three entity sets (Airlines, Airports, People), which would be exposed as Tables in M, and skip the singleton (Me) which would be exposed as a Record. 関数の追加は、後のレッスンまでスキップします。You'll skip adding the functions until a later lesson.

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

次に、関数を更新して、 TripPinNavTable 一度に1列ずつテーブルを作成します。You then update your TripPinNavTable function to build the table a column at a time. 各エンティティの [Data] 列は、エンティティへの完全な URL を使用してを呼び出すことによって取得され TripPin.Feed ます。The [Data] column for each entity is retrieved by calling TripPin.Feed with the full URL to the entity.

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;

URL パスを動的に作成する場合は、スラッシュ (/) の場所を明確にしてください。When dynamically building URL paths, make sure you're clear where your forward slashes (/) are! Uri は、パスを結合するときに次の規則を使用することに注意してください。Note that Uri.Combine uses the following rules when combining paths:

  • パラメーターが relativeUri /で始まる場合、パラメーターのパス全体が置換されます baseUriWhen the relativeUri parameter starts with a /, it will replace the entire path of the baseUri parameter
  • パラメーターが relativeUri /で始まら 、/で終わる場合は、 baseUri パスが追加されます。If the relativeUri parameter does not start with a / and baseUri ends with a /, the path is appended
  • パラメーターが relativeUri /で始まら baseUri またはで終わら ない 場合は、パスの最後のセグメントが置き換えられます。If the relativeUri parameter does not start with a / and baseUri does not end with a /, the last segment of the path is replaced

次の図は、この例を示しています。The following image shows examples of this:

Uri. 結合の例

エンティティ固有の関数を削除するRemove the Entity Specific Functions

コネクタの保守を容易にするために、前のレッスン「」および「」で使用したエンティティ固有の書式関数を削除し — GetAirlineTables GetAirportsTable ます。To make your connector easier to maintain, you'll remove the entity specific formatting functions you used in the previous lesson—GetAirlineTables and GetAirportsTable. 代わりに、 TripPin.Feed すべてのエンティティに対して機能するように、JSON 応答を処理するようにを更新します。Instead, you'll update TripPin.Feed to process the JSON response in a way that will work for all of your entities. 具体的には、 value 返された ODATA JSON ペイロードのフィールドを取得し、レコードのリストからテーブルに変換します。Specifically, you take the value field of the returned OData JSON payload, and convert it from a list of records to a table.

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;

注意

一般的な方法を使用してエンティティを処理することの欠点は、エンティティの見栄えの良い書式情報と型情報が失われることです。A disadvantage of using a generic approach to process your entities is that you lose the nice formating and type information for your entities. このチュートリアルの後のセクションでは、REST API 呼び出しにスキーマを適用する方法を示します。A later section in this tutorial shows how to enforce schema on REST API calls.

結論Conclusion

このチュートリアルでは、データソースパスの値を修正し、ナビゲーションテーブルのより柔軟な形式に移行することで、コネクタをクリーンアップし、簡素化しました。In this tutorial, you cleaned up and simplified your connector by fixing your Data Source Path value, and moving to a more flexible format for your navigation table. これらの手順を完了すると (または、このディレクトリのサンプルコードを使用して)、 TripPin.Contents 関数は Power BI Desktop 内のナビゲーションテーブルを返します。After completing these steps (or using the sample code in this directory), the TripPin.Contents function returns a navigation table in Power BI Desktop.

ナビゲーター

次のステップNext steps

TripPin Part 5-ページングTripPin Part 5 - Paging