Share via


チュートリアル: Azure Static Web Apps で Azure Cosmos DB データベース接続を追加する (プレビュー)

このチュートリアルでは、静的 Web アプリに Azure Cosmos DB for NoSQL データベースを接続する方法について説明します。 構成しておくと、組み込みの /data-api エンドポイントに対して GraphQL 要求を行うことで、バックエンド コードを記述しなくてもデータを操作できます。

わかりやすくするために、このチュートリアルでは、ローカル開発の目的で Azure データベースを使用する方法について説明しますが、ローカル開発のニーズのためにローカル データベース サーバーを使用することもできます。

注意

このチュートリアルでは、Azure Cosmos DB for NoSQL を使用する方法について説明します。 別のデータベースを使用する場合は、Azure SQLMySQL、または PostgreSQL のチュートリアルを参照してください。

開発者ツール コンソール ウィンドウでの Cosmos DB からの結果を示す Web ブラウザー。

このチュートリアルで学習する内容は次のとおりです。

  • 静的 Web アプリに Azure Cosmos DB for NoSQL データベースをリンクする
  • データの作成、読み取り、更新、削除を行う

前提条件

このチュートリアルを完了するには、既存の Azure Cosmos DB for NoSQL データベースと静的 Web アプリが必要です。

リソース 説明
Azure Cosmos DB for NoSQL データベース まだない場合は、「Azure Cosmos DB データベースを作成する」ガイドの手順に従います。
既存の静的 Web アプリ まだない場合は、ファースト ステップ ガイドの手順に従って、"フレームワークなし" の静的 Web アプリを作成します。

まず、Azure Static Web Apps データベース接続機能を使用するようにデータベースを構成します。

データベース接続を構成する

データベース接続が機能するためには、Azure Static Web Apps がデータベースにネットワーク アクセスできる必要があります。 さらに、ローカル開発のために Azure データベースを使用するには、自分の IP アドレスからの要求を許可するようにデータベースを構成する必要があります。

  1. Azure portal で Azure Cosmos DB for NoSQL アカウントに移動します。

  2. [設定] セクションで、[ネットワーク] を選択します。

  3. [パブリック アクセス] セクションで、[すべてのネットワーク] を選択します。 このアクションを使用すると、ローカル開発のためにクラウド データベースを使用できます。デプロイされた Static Web Apps リソースはデータベースにアクセスでき、ポータルからデータベースに対してクエリを実行できます。

  4. [保存] を選択します。

ローカル開発用のデータベース接続文字列を取得する

Azure データベースをローカル開発に使用するには、データベースの接続文字列を取得する必要があります。 開発の目的でローカル データベースを使用する予定の場合は、この手順を省略できます。

  1. Azure portal で Azure Cosmos DB for NoSQL アカウントに移動します。

  2. [設定] セクションで、[キー] を選択します。

  3. [プライマリ接続文字列] ボックスから、接続文字列をコピーし、テキスト エディターに貼り付けておきます。

サンプル データの作成

サンプル テーブルを作成し、チュートリアルと一致するサンプル データを使用してシード処理します。

  1. 左側のナビゲーション ウィンドウで、[Data Explorer] を選択します。

  2. [新しいコンテナー] を選択します。 [データベース ID] として Create new を入力し、値として MyTestPersonDatabase を入力します。

  3. [コンテナー ID] として MyTestPersonContainer を入力します。

  4. パーティション キーとして id を入力します (この値の前に / が付きます)。

  5. [OK] を選択します。

  6. MyTestPersonContainer コンテナーを選択します。

  7. その [項目] を選択します。

  8. [新しい項目] を選択し、次の値を入力します。

    {
        "id": "1",
        "Name": "Sunny"
    }
    

静的 Web アプリを構成する

このチュートリアルの残りの部分では、ローカルでデータベース接続を使用するように静的 Web アプリのソース コードを編集することに重点を置いています。

重要

次の手順では、ファースト ステップ ガイドで作成した静的 Web アプリを使用していることを前提としています。 別のプロジェクトを使用している場合は、ブランチ名と一致するように次の git コマンドを調整してください。

  1. main ブランチに切り替えます。

    git checkout main
    
  2. git pull を使用して、ローカル バージョンを GitHub 上のバージョンと同期します。

    git pull origin main
    

データベース構成ファイルを作成する

次に、静的 Web アプリがデータベースとのインターフェイスに使用する構成ファイルを作成します。

  1. ターミナルを開き、接続文字列を保持する新しい変数を作成します。 具体的な構文は、使用しているシェルの種類によって異なる場合があります。

    export DATABASE_CONNECTION_STRING='<YOUR_CONNECTION_STRING>'
    

    <YOUR_CONNECTION_STRING> を、テキスト エディターに貼り付けておいた接続文字列の値に必ず置き換えてください。

  2. npm を使用して、Static Web Apps CLI をインストールまたは更新します。 ご自分の状況に最も適したコマンドを選択します。

    インストールするには、npm install を使用します。

    npm install -g @azure/static-web-apps-cli
    

    更新するには、npm update を使用します。

    npm update
    
  3. swa db init コマンドを使用して、データベース構成ファイルを生成します。

    swa db init --database-type cosmosdb_nosql --cosmosdb_nosql-database MyTestPersonDatabase
    

    init コマンドでは、swa-db-connections フォルダーに staticwebapp.database.config.json ファイルが作成されます。

  4. このサンプル スキーマを、生成した staticwebapp.database.schema.gql ファイルに貼り付けます。

    Cosmos DB for NoSQL はスキーマに依存しないデータベースであるため、Azure Static Web Apps データベース接続はデータベースのスキーマを抽出できません。 staticwebapp.database.schema.gql ファイルを使用すると、Static Web Apps 用の Cosmos DB for NoSQL データベースのスキーマを指定できます。

    type Person @model {
      id: ID
      Name: String
    }
    
  5. このサンプル構成を、生成した staticwebapp.database.config.json ファイルに貼り付けます。 Cosmos DB for NoSQL の data-source オブジェクトには、Cosmos DB データベースと、データベース接続がデータベースのスキーマを認識するために必要なスキーマ ファイルを指定するための追加のオプションがあることに注意してください。

{
  "$schema": "https://github.com/Azure/data-api-builder/releases/latest/download/dab.draft.schema.json",
  "data-source": {
    "database-type": "cosmosdb_nosql",
    "options": {
      "database": "MyTestPersonDatabase",
      "schema": "staticwebapp.database.schema.gql"
    },
    "connection-string": "@env('DATABASE_CONNECTION_STRING')"
  },
  "runtime": {
    "graphql": {
      "allow-introspection": true,
      "enabled": true,
      "path": "/graphql"
    },
    "host": {
      "mode": "production",
      "cors": {
        "origins": ["http://localhost:4280"],
        "allow-credentials": false
      },
      "authentication": {
        "provider": "StaticWebApps"
      }
    }
  },
  "entities": {
    "Person": {
      "source": "MyTestPersonContainer",
      "permissions": [
        {
          "actions": ["*"],
          "role": "anonymous"
        }
      ]
    }
  }
}

次の手順に進む前に、構成ファイルのさまざまな側面について説明する次の表を確認してください。 構成ファイルと、項目レベルのセキュリティに関するリレーションシップやポリシーなどの機能の詳細な説明については、Data API Builder のドキュメントを参照してください。

機能 説明
データベース接続 開発時に、ランタイムによって構成ファイル内の接続文字列の値から接続文字列が読み取られます。 接続文字列は構成ファイルに直接指定できますが、ベスト プラクティスは、接続文字列をローカル環境変数に格納することです。 構成ファイル内の環境変数の値は、@env('DATABASE_CONNECTION_STRING') 表記を介して参照できます。 接続文字列の値は、データベースを接続するときに収集された情報を使用して、デプロイされたサイトの Static Web Apps によって上書きされます。
API エンドポイント GraphQL エンドポイントは、この構成ファイル内で構成されているように /data-api/graphql を介して使用できます。 GraphQL パスは構成できますが、/data-api プレフィックスは構成できません。
API セキュリティ runtime.host.cors 設定を使用すると、API に対して要求を行うことができる許可された配信元を定義できます。 この場合、構成には開発環境が反映され、http://localhost:4280 の場所が許可リストに載せられます。
エンティティ モデル ルートを介して公開されるエンティティを GraphQL スキーマ内の種類として定義します。 この場合、Person という名前は、エンドポイントに公開される名前であり、entities.<NAME>.source は、データベース スキーマとテーブルのマッピングです。 API エンドポイント名がテーブル名と同じである必要がないことに注意してください。
エンティティのセキュリティ entity.<NAME>.permissions 配列に一覧表示されているアクセス許可ルールは、エンティティの承認設定を制御します。 ロールを使用してルートをセキュリティで保護するのと同様に、ロールを使用してエンティティをセキュリティで保護することができます。

注意

構成ファイルの connection-stringhost.modegraphql.allow-introspection プロパティは、サイトをデプロイするときに上書きされます。 接続文字列は、Static Web Apps リソースにデータベースを接続するときに収集された認証の詳細で上書きされます。 host.mode プロパティが production に設定され、graphql.allow-introspectionfalse に設定されます。 これらのオーバーライドにより、開発と運用ワークロード全体で構成ファイルの一貫性が確保され、データベース接続が有効になっている Static Web Apps リソースがセキュリティで保護され、運用に対応できるようになります。

静的 Web アプリがデータベースに接続するように構成されたので、接続を確認できるようになりました。

ホーム ページの更新

index.html ファイル内の body タグ間のマークアップを、次の HTML に置き換えます。

<h1>Static Web Apps Database Connections</h1>
<blockquote>
    Open the console in the browser developer tools to see the API responses.
</blockquote>
<div>
    <button id="list" onclick="list()">List</button>
    <button id="get" onclick="get()">Get</button>
    <button id="update" onclick="update()">Update</button>
    <button id="create" onclick="create()">Create</button>
    <button id="delete" onclick="del()">Delete</button>
</div>
<script>
    // add JavaScript here
</script>

ローカルでアプリケーションを起動する

Web サイトを実行し、データベース内のデータを直接操作することができるようになりました。

  1. npm を使用して、Static Web Apps CLI をインストールまたは更新します。 ご自分の状況に最も適したコマンドを選択します。

    インストールするには、npm install を使用します。

    npm install -g @azure/static-web-apps-cli
    

    更新するには、npm update を使用します。

    npm update
    
  2. データベース構成を使用して静的 Web アプリを起動します。

    swa start ./src --data-api-location swa-db-connections
    

CLI が開始されたので、staticwebapp.database.config.json ファイルで定義されたエンドポイントを介してデータベースにアクセスできます。

http://localhost:4280/data-api/graphql エンドポイントは、GraphQL クエリとミューテーションを受け入れます。

データを操作する

フレームワークに依存しない次のコマンドは、データベースに対して完全な CRUD 操作を実行する方法を示しています。

各関数の出力がブラウザーのコンソール ウィンドウに表示されます。

CMD/Ctrl + Shift + I キーを押して開発者ツールを開き、[コンソール] タブを選択します。

すべての項目を一覧表示する

index.html 内の script タグ間に次のコードを追加します。

async function list() {

  const query = `
      {
        people {
          items {
            id
            Name
          }
        }
      }`;
      
  const endpoint = "/data-api/graphql";
  const response = await fetch(endpoint, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ query: query })
  });
  const result = await response.json();
  console.table(result.data.people.items);
}

次の点に注意してください。

  • GraphQL クエリは、データベースから Id フィールドと Name フィールドを選択します。
  • サーバーに渡される要求には、query プロパティにクエリ定義が保持されているペイロードが必要です。
  • 応答ペイロード内のデータは、data.people.items プロパティにあります。

ページを更新し、[一覧表示] ボタンを選択します。

ブラウザーのコンソール ウィンドウに、データベース内のすべてのレコードを一覧表示するテーブルが表示されるようになりました。

id 名前
1 晴れ
2 Dheeraj

ブラウザーに表示される内容のスクリーンショットを次に示します。

開発者ツール コンソール ウィンドウでのデータベース選択からの結果を示す Web ブラウザー。

ID で取得する

index.html 内の script タグ間に次のコードを追加します。

async function get() {

  const id = '1';

  const gql = `
    query getById($id: ID!) {
      person_by_pk(id: $id) {
        id
        Name
      }
    }`;

  const query = {
    query: gql,
    variables: {
      id: id,
    },
  };

  const endpoint = "/data-api/graphql";
  const response = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query),
  });
  const result = await response.json();
  console.table(result.data.person_by_pk);
}

次の点に注意してください。

  • GraphQL クエリは、データベースから id フィールドと Name フィールドを選択します。
  • サーバーに渡される要求には、query プロパティにクエリ定義が保持されているペイロードが必要です。
  • 応答ペイロード内のデータは、data.person_by_pk プロパティにあります。

ページを更新し、[取得] ボタンを選択します。

ブラウザーのコンソール ウィンドウに、データベースから要求された 1 つのレコードを一覧表示するテーブルが表示されるようになりました。

id 名前
1 晴れ

更新

index.html 内の script タグ間に次のコードを追加します。

async function update() {

  const id = '1';
  const data = {
    id: id,
    Name: "Molly"
  };

  const gql = `
    mutation update($id: ID!, $_partitionKeyValue: String!, $item: UpdatePersonInput!) {
      updatePerson(id: $id, _partitionKeyValue: $_partitionKeyValue, item: $item) {
        id
        Name
      }
    }`;

  const query = {
    query: gql,
    variables: {
      id: id,
      _partitionKeyValue: id,
      item: data
    } 
  };

  const endpoint = "/data-api/graphql";
  const res = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query)
  });

  const result = await res.json();
  console.table(result.data.updatePerson);
}

次の点に注意してください。

  • GraphQL クエリは、データベースから id フィールドと Name フィールドを選択します。
  • query オブジェクトでは、GraphQL クエリが query プロパティ内に保持されます。
  • GraphQL 関数への引数値は、query.variables プロパティを介して渡されます。
  • サーバーに渡される要求には、query プロパティにクエリ定義が保持されているペイロードが必要です。
  • 応答ペイロード内のデータは、data.updatePerson プロパティにあります。

ページを更新し、[更新] ボタンを選択します。

ブラウザーのコンソール ウィンドウに、更新されたデータを示すテーブルが表示されるようになりました。

id 名前
1 Molly

作成

index.html 内の script タグ間に次のコードを追加します。

async function create() {

  const data = {
    id: "3",
    Name: "Pedro"
  };

  const gql = `
    mutation create($item: CreatePersonInput!) {
      createPerson(item: $item) {
        id
        Name
      }
    }`;
  
  const query = {
    query: gql,
    variables: {
      item: data
    } 
  };
  
  const endpoint = "/data-api/graphql";
  const result = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query)
  });

  const response = await result.json();
  console.table(response.data.createPerson);
}

次の点に注意してください。

  • GraphQL クエリは、データベースから id フィールドと Name フィールドを選択します。
  • query オブジェクトでは、GraphQL クエリが query プロパティ内に保持されます。
  • GraphQL 関数への引数値は、query.variables プロパティを介して渡されます。
  • サーバーに渡される要求には、query プロパティにクエリ定義が保持されているペイロードが必要です。
  • 応答ペイロード内のデータは、data.updatePerson プロパティにあります。

ページを更新し、[作成] ボタンを選択します。

ブラウザーのコンソール ウィンドウに、データベース内の新しいレコードを示すテーブルが表示されるようになりました。

id 名前
3 Pedro

削除

index.html 内の script タグ間に次のコードを追加します。

async function del() {

  const id = '3';

  const gql = `
    mutation del($id: ID!, $_partitionKeyValue: String!) {
      deletePerson(id: $id, _partitionKeyValue: $_partitionKeyValue) {
        id
      }
    }`;

  const query = {
    query: gql,
    variables: {
      id: id,
    _partitionKeyValue: id
    }
  };

  const endpoint = "/data-api/graphql";
  const response = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query)
  });

  const result = await response.json();
  console.log(`Record deleted: ${ JSON.stringify(result.data) }`);
}

次の点に注意してください。

  • GraphQL クエリで、データベースから Id フィールドが選択されます。
  • query オブジェクトでは、GraphQL クエリが query プロパティ内に保持されます。
  • GraphQL 関数への引数値は、query.variables プロパティを介して渡されます。
  • サーバーに渡される要求には、query プロパティにクエリ定義が保持されているペイロードが必要です。
  • 応答ペイロード内のデータは、data.deletePerson プロパティにあります。

ページを更新し、[削除] ボタンを選択します。

ブラウザーのコンソール ウィンドウに、削除要求からの応答を示すテーブルが表示されるようになりました。

"削除されたレコード: 2"

ローカルでサイトを操作したので、Azure にデプロイできるようになりました。

サイトのデプロイ

このサイトを運用環境にデプロイするために必要なのは、構成ファイルをコミットし、変更をサーバーにプッシュすることだけです。

  1. 構成の変更をコミットします。

    git commit -am "Add database configuration"
    
  2. 変更をサーバーにプッシュします。

    git push origin main
    
  3. Web アプリがビルドされるまで待ちます。

  4. ブラウザーで静的 Web アプリに移動します。

  5. [一覧表示] ボタンを選択して、すべての項目を一覧表示します。

    出力は、こちらのスクリーンショットのようになります。

    開発者ツール コンソール ウィンドウでのデータベースからのレコードの一覧表示の結果を示す Web ブラウザー。

静的 Web アプリにデータベースを接続する

サイトの Static Web Apps インスタンスとデータベースの間の接続を作成するには、次の手順に従います。

  1. Azure portal で静的 Web アプリを開く

  2. [設定] セクションで、[データベース接続] を選択します。

  3. [運用] セクションで、[既存のデータベースのリンク] リンクを選択します。

  4. [既存のデータベースのリンク] ウィンドウで、次の値を入力します。

    プロパティ
    データベースの種類 ドロップダウン リストからデータベースの種類を選択します。
    サブスクリプション ドロップダウン リストから Azure サブスクリプションを選択します。
    データベース名 静的 Web アプリにリンクするデータベースの名前を選択します。
    認証の種類 [接続文字列] を選択します。
  5. [OK] を選択します。

データベースが Static Web Apps リソースに接続されていることを確認する

静的 Web アプリにデータベースを接続し、サイトの構築が完了したら、次の手順に従ってデータベース接続を確認します。

  1. Azure portal で静的 Web アプリを開く

  2. [要点] セクションで、Static Web Apps リソースの [URL] を選択して、静的 Web アプリに移動します。

  3. [一覧表示] ボタンを選択して、すべての項目を一覧表示します。

    出力は、こちらのスクリーンショットのようになります。

    開発者ツール コンソール ウィンドウでのデータベースからのレコードの一覧表示の結果を示す Web ブラウザー。

リソースをクリーンアップする

このチュートリアルで作成したリソースを削除する場合は、データベースのリンクを解除し、サンプル データを削除する必要があります。

  1. データベースのリンク解除: Azure portal で静的 Web アプリを開きます。 [設定] セクションで、[データベース接続] を選択します。 リンクされたデータベースの横で、[詳細の表示] を選択します。 [データベース接続の詳細] ウィンドウで、[リンク解除] ボタンを選択します。

  2. サンプル データの削除: データベースで、MyTestPersonContainer という名前のテーブルを削除します。

次のステップ