チュートリアル: ポータル Web API を使用する

注意

2022 年 10 月 12 日より、Power Apps ポータルは Power Pages となります。 詳細: Microsoft Power Pages の一般提供が開始されました (ブログ)
Power Apps ポータルのドキュメントは、近日中に Power Pages ドキュメントに移行、統合されます。

このチュートリアルでは、Web API を使用して連絡先テーブルのレコードの読み取り、書き込み、更新、および削除を行う Web ページとカスタム Web テンプレートを設定します。

注意

この例の手順に従って、列名を変更したり、別のテーブルを使用したりできます。

ステップ 1: サイトの設定の作成

ポータル WebAPI を使用する前に、ポータル管理アプリで必要なサイト設定を有効にする必要があります。 サイト設定は、Web API を操作する場合に使用するテーブルによって異なります。

  1.  Power Apps に移動します。

  2. 左側のペインで、 アプリを選択します。

  3.  ポータル管理 アプリを選択します。

    ポータル管理アプリを起動する。

  4.  ポータル管理  アプリの左側のウィンドウで、 サイト設定 を選択します。

    ポータル管理アプリでサイト設定を開きます。

  5.  新規を選択します。

  6.  名前  ボックスに、 Webapi/contact/enabled と入力します。

  7.  Web サイト  リストで、Web サイト レコードを選択します。

  8.  数値  ボックスに、 true と入力します。

    Web API サイト設定の連絡先テーブルを有効にします。

  9.  保存して閉じるを選択します。

  10.  新規を選択します。

  11.  名前  ボックスに、 Webapi/contact/fields と入力します。

  12.  Web サイト  リストで、Web サイト レコードを選択します。

  13.    ボックスで、次を入力します
    firstname,lastname,fullname,emailaddress1,telephone1

    Web API の連絡先テーブル フィールド サイト設定を有効にします。

  14.  保存して閉じるを選択します。

  15.  新規を選択します。

  16.  名前  ボックスに、 Webapi/error/innererror と入力します。

    Web API 内部エラー サイト設定を有効にします。

  17.  Web サイト  リストで、Web サイト レコードを選択します。

  18.  数値  ボックスに、 true と入力します。

  19.  保存して閉じるを選択します。

  20.  Web API のサイト設定を検証します。

ステップ 2. アクセス許可の構成

ユーザーが WebAPI 機能を使用できるように、アクセス許可を構成する必要があります。 この例では、テーブル アクセス許可用の 連絡先 テーブルを有効にし、Web API を使用して Web ロールを作成し、連絡先 テーブルのテーブル アクセス許可をこの Web ロールに追加してから、ユーザーが Web API を使用できるように Web ロールをユーザーに追加します。

  1.  ポータル管理  アプリの左側のウィンドウで、 テーブルへのアクセス許可 を選択します。

  2.  新規を選択します。

  3.  名前 ボックスで 取引先担当者テーブルのアクセス許可を入力します。

  4.  テーブル名 リストで、 取引先担当者 (取引先担当者) を選択します。

  5.  Web サイト  リストで、Web サイト レコードを選択します。

  6.  アクセスの種類 リストで、 グローバルを選択します。

  7. 読み取り書き込み作成削除 の特権を選択します。

  8.  保存して閉じるを選択します。

    連絡先テーブルへのアクセス許可。

Web ロールを作成する

Web サイトで既存の Web ロールを使用するか、新しい Web ロールを作成できます。

  1. 左ペインで、 Web ロール  を選択します。

  2.  新規を選択します。

  3.  名前  ボックスで、 Web API ユーザー (または、この機能にアクセスするユーザーの役割を最もよく反映する任意の名前) を入力します。

  4.  Web サイト  リストで、Web サイト レコードを選択します。

    Web API ユーザー Web ロールを追加します。

  5.  保存を選択します。

関連テーブルのアクセス許可を追加する

  1. 新規または既存の Web ロールで、 関連 > テーブルのアクセス権限 を選択します。

    関連したテーブルへのアクセス許可を Web ロールに追加します。

  2.  既存テーブルのアクセス許可の追加を選択します。

  3. 以前に作成した、 取引先担当者テーブルのアクセス許可を選択します。

    連絡先テーブルへのアクセス許可を選択します。

  4.  追加を選択します。

  5.  保存して閉じるを選択します。

    テーブルのアクセス許可ビュー。

取引先担当者を Web ロールに追加する

  1. 左側ペインで、 取引先担当者 を選択します。

  2. Web API に対してこの例を使用する取引先担当者を選択します。

    注意

    この取引先担当者は、この例で WebAPI をテストするために使用されるユーザー アカウントです。 必ずポータルで正しい連絡先を選択してください。

  3.  関連 > Web ロール を選択します。

    関連した Web ロールの選択。

  4.  既存の Web ロールの追加 を選択します。

  5. 以前に作成した、 Web API ユーザー  ロールを選択します。

  6.  追加を選択します。

    Web ロール関連ビュー。

  7.  保存して閉じるを選択します。

ステップ 3. Web ページの作成

Web API を有効にし、ユーザー権限を構成したので、レコードを表示、編集、作成、および削除するためのサンプルコードを使用して Web ページを作成します。

  1.  ポータル管理  アプリの左側のウィンドウで、Web ページ を選択します。

  2. 新規 を選択します。

  3. 名前 ボックスに、webapi と入力します。

  4. Web サイト リストで、Web サイト レコードを選択します。

  5. 親ページ には、ホーム を選択します。

  6. 部分的な URL には、webapi と入力します。

  7. 親テンプレート には、ホーム を選択します。

  8. 公開状況 には、 公開済み を選択します。

  9. 保存を選びます。

    Web ページ。

  10. 関連 > Web ページ を選択します。

    関連する Web ページ

  11. Web ページ関連ビュー から、webapi を選択します。

    Web ページ関連ビュー。

  12. コンテンツ セクションまでスクロール ダウンして、コピー (HTML) ( + +HTML デザイナー) へと移動します。

    HTML コンテンツのコピー

  13. HTML タブを選択します。

    HTML タブを選択します

  14. 次のサンプル コード スニペットをコピーして、HTML デザイナーに貼り付けます。

        <!-- Sample code for Web API demonstration -->
    <style>
        #processingMsg {
            width: 150px;
            text-align: center;
            padding: 6px 10px;
            z-index: 9999;
            top: 0;
            left: 40%;
            position: fixed;
            -webkit-border-radius: 0 0 2px 2px;
            border-radius: 0 0 2px 2px;
            -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
            display: none;
        }
    
        table td[data-attribute] .glyphicon-pencil {
            margin-left: 5px;
            opacity: 0;
        }
    
        table td[data-attribute]:hover .glyphicon-pencil {
            opacity: 0.7;
        }
    </style>
    
    <script>
      $(function() {
        //Web API ajax wrapper
        (function(webapi, $) {
          function safeAjax(ajaxOptions) {
            var deferredAjax = $.Deferred();
            shell.getTokenDeferred().done(function(token) {
              // Add headers for ajax
              if (!ajaxOptions.headers) {
                $.extend(ajaxOptions, {
                  headers: {
                    "__RequestVerificationToken": token
                  }
                });
              } else {
                ajaxOptions.headers["__RequestVerificationToken"] = token;
              }
              $.ajax(ajaxOptions)
                .done(function(data, textStatus, jqXHR) {
                  validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
                }).fail(deferredAjax.reject); //ajax
            }).fail(function() {
              deferredAjax.rejectWith(this, arguments); // On token failure pass the token ajax and args
            });
            return deferredAjax.promise();
          }
          webapi.safeAjax = safeAjax;
        })(window.webapi = window.webapi || {}, jQuery)
        // Notification component
        var notificationMsg = (function() {
          var $processingMsgEl = $('#processingMsg'),
            _msg = 'Processing...',
            _stack = 0,
            _endTimeout;
          return {
            show: function(msg) {
              $processingMsgEl.text(msg || _msg);
              if (_stack === 0) {
                clearTimeout(_endTimeout);
                $processingMsgEl.show();
              }
              _stack++;
            },
            hide: function() {
              _stack--;
              if (_stack <= 0) {
                _stack = 0;
                clearTimeout(_endTimeout);
                _endTimeout = setTimeout(function() {
                  $processingMsgEl.hide();
                }, 500);
              }
            }
          }
        })();
        // Inline editable table component
        var webAPIExampleTable = (function() {
          var trTpl = '<% _.forEach(data, function(data){ %>' +
            '<tr data-id="<%=data.id%>" data-name="<%=data.fullname%>">' +
            '<% _.forEach(columns, function(col){ %>' +
            '<td data-attribute="<%=col.name%>" data-label="<%=col.label%>" data-value="<%=data[col.name]%>">' +
            '<%-data[col.name]%><i class="glyphicon glyphicon-pencil"></i>' +
            '</td>' +
            '<% }) %>' +
            '<td>' +
            '<button class="btn btn-default delete" type="submit"><i class="glyphicon glyphicon-trash" aria-hidden="true"></i></button>' +
            '</td>' +
            '</tr>' +
            '<% }) %>';
          var tableTpl = '<table class="table table-hover">' +
            '<thead>' +
            '<tr>' +
            '<% _.forEach(columns, function(col){ %>' +
            '<th><%=col.label%></th>' +
            '<% }) %>' +
            '<th>' +
            '<button class="btn btn-default add" type="submit">' +
            '<i class="glyphicon glyphicon-plus" aria-hidden="true"></i> Add Sample Record' +
            '</button>' +
            '</th>' +
            '</tr>' +
            '</thead>' +
            '<tbody>' + trTpl + '</tbody>' +
            '</table>';
          function getDataObject(rowEl) {
            var $rowEl = $(rowEl),
              attrObj = {
                id: $rowEl.attr('data-id'),
                name: $rowEl.attr('data-name')
              };
            $rowEl.find('td').each(function(i, el) {
              var $el = $(el),
                key = $el.attr('data-attribute');
              if (key) {
                attrObj[key] = $el.attr('data-value');
              }
            })
            return attrObj;
          }
          function bindRowEvents(tr, config) {
            var $row = $(tr),
              $deleteButton = $row.find('button.delete'),
              dataObj = getDataObject($row);
            $.each(config.columns, function(i, col) {
              var $el = $row.find('td[data-attribute="' + col.name + '"]');
              $el.on('click', $.proxy(col.handler, $el, col, dataObj));
            });
            //User can delete record using this button
            $deleteButton.on('click', $.proxy(config.deleteHandler, $row, dataObj));
          }
          function bindTableEvents($table, config) {
            $table.find('tbody tr').each(function(i, tr) {
              bindRowEvents(tr, config);
            });
            $table.find('thead button.add').on('click', $.proxy(config.addHandler, $table));
          }
          return function(config) {
            var me = this,
              columns = config.columns,
              addHandler = config.addHandler,
              deleteHandler = config.deleteHandler,
              $table;
            me.render = function(el) {
              $table = $(el).html(_.template(tableTpl)({
                columns: columns,
                data: me.data
              })).find('table');
              bindTableEvents($table, {
                columns: columns,
                addHandler: addHandler,
                deleteHandler: deleteHandler
              });
            }
            me.addRecord = function(record) {
              $table.find('tbody tr:first').before(_.template(trTpl)({
                columns: columns,
                data: [record]
              }));
              bindRowEvents($table.find('tbody tr:first'), config);
            }
            me.updateRecord = function(attributeName, newValue, record) {
              $table.find('tr[data-id="' + record.id + '"] td[data-attribute="' + attributeName + '"]').text(newValue);
            }
            me.removeRecord = function(record) {
              $table.find('tr[data-id="' + record.id + '"]').fadeTo("slow", 0.7, function() {
                $(this).remove();
              });
            }
          };
        })();
        //Applicaton ajax wrapper 
        function appAjax(processingMsg, ajaxOptions) {
          notificationMsg.show(processingMsg);
          return webapi.safeAjax(ajaxOptions)
            .fail(function(response) {
              if (response.responseJSON) {
                alert("Error: " + response.responseJSON.error.message)
              } else {
                alert("Error: Web API is not available... ")
              }
            }).always(notificationMsg.hide);
        }
        function loadRecords() {
          return appAjax('Loading...', {
            type: "GET",
            url: "/_api/contacts?$select=fullname,firstname,lastname,emailaddress1,telephone1",
            contentType: "application/json"
          });
        }
        function addSampleRecord() {
          //Sample data to create a record - change as appropriate
          var recordObj = {
            firstname: "Willie",
            lastname: "Huff" + _.random(100, 999),
            emailaddress1: "Willie.Huff@contoso.com",
            telephone1: "555-123-4567"
          };
          appAjax('Adding...', {
            type: "POST",
            url: "/_api/contacts",
            contentType: "application/json",
            data: JSON.stringify(recordObj),
            success: function(res, status, xhr) {
              recordObj.id = xhr.getResponseHeader("entityid");
              recordObj.fullname = recordObj.firstname + " " + recordObj.lastname;
              table.addRecord(recordObj);
            }
          });
          return false;
        }
        function deleteRecord(recordObj) {
          var response = confirm("Are you sure, you want to delete \"" + recordObj.name + "\" ?");
          if (response == true) {
            appAjax('Deleting...', {
              type: "DELETE",
              url: "/_api/contacts(" + recordObj.id + ")",
              contentType: "application/json",
              success: function(res) {
                table.removeRecord(recordObj);
              }
            });
          }
          return false;
        }
        function updateRecordAttribute(col, recordObj) {
          var attributeName = col.name,
            value = recordObj[attributeName],
            newValue = prompt("Please enter \"" + col.label + "\"", value);
          if (newValue != null && newValue !== value) {
            appAjax('Updating...', {
              type: "PUT",
              url: "/_api/contacts(" + recordObj.id + ")/" + attributeName,
              contentType: "application/json",
              data: JSON.stringify({
                "value": newValue
              }),
              success: function(res) {
                table.updateRecord(attributeName, newValue, recordObj);
              }
            });
          }
          return false;
        }
        var table = new webAPIExampleTable({
          columns: [{
            name: 'firstname',
            label: 'First Name',
            handler: updateRecordAttribute
          }, {
            name: 'lastname',
            label: 'Last Name',
            handler: updateRecordAttribute
          }, {
            name: 'emailaddress1',
            label: 'Email',
            handler: updateRecordAttribute
          }, {
            name: 'telephone1',
            label: 'Telephone',
            handler: updateRecordAttribute
          }],
          data: [],
          addHandler: addSampleRecord,
          deleteHandler: deleteRecord
        });
        loadRecords().done(function(data) {
          table.data = _.map(data.value, function(record){
            record.id = record.contactid;
            return record;
          });
          table.render($('#dataTable'));
        });
      });
    </script>
    <div id="processingMsg" class="alert alert-warning" role="alert"></div>
    <div id="dataTable"></div>
    

    コードを貼り付けます。

  15. 保存して閉じるを選択します。

ステップ 4. ポータルのキャッシュをクリアする

Web API 機能をテストする  webapi  サンプルページを作成しました。 始める前に、Power Apps ポータル管理アプリからの変更がポータルに反映されるように、ポータル キャッシュがクリアされました。

重要: ポータルのサーバー側キャッシュをクリアすることで、Microsoft Dataverse からデータを再度読み込みをしている間、一時的にポータルのパフォーマンスが低下することがあります。

キャッシュをクリアするには、

  1. 管理者の Web ロールのメンバーとしてポータルにサインインします。

  2. 最後に  /_‑services/about  を追加して URL を変更します。 たとえば、ポータル URL が  https://contoso.powerappsportals.com の場合、 https://contoso.powerappsportals.com/_services/about に変更します。

    キャッシュのクリア。

    注: キャッシュをクリアするには、 管理者 Webロールのメンバーでなければなりません。 空白のスクリーンが表示される場合は、Web ロールの割り当てを確認してください。

  3.  キャッシュのクリアを選択します。

詳細:  ポータルのサーバー サイド キャッシュをクリアする

ステップ 5: Web API を使用して、読み取り、表示、編集、作成、および削除を実行します

以前に作成した URL webapi を含むサンプル Web ページをテストする準備が整いました。

Web API 機能をテストするには:

  1. 以前に作成した WebAPI ユーザー ロールに割り当てられたユーザー アカウントでポータルにログインします。

  2. 以前に作成された webapi Webページに移動します。 たとえば、https://contoso.powerappsportals.com/webapi などとします。 WebAPI は Microsoft Dataverse からレコードを取得します。

    サンプル webapi webpage。

  3. サンプル レコードを追加 を選択して、スクリプトからサンプル レコードを追加します。

  4. フィールドを選択します。 この例では、E メール を選択して、取引先担当者のメール アドレスを変更します。

    電子メールの編集

  5. ボタンの削除 を選択してレコードを削除します。

レコードを読み取り、編集、作成、および削除するためのサンプルを含む Web ページを作成したので、フォームとレイアウトをカスタマイズできます。

次のステップ

HTTP 要求の作成とエラーの処理

関連情報

ポータル Web API の概要
ポータルは、Web API を使用して操作を書き込み、更新、および削除します
Web API を使用したポータルの読み込み操作
列のアクセス許可を構成する

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。