チュートリアル: Azure Static Web Apps で MySQL データベース接続を追加する (プレビュー)
このチュートリアルでは、Azure Database for MySQL フレキシブル サーバー データベースを静的 Web アプリに接続する方法について説明します。 構成しておくと、組み込みの /data-api
エンドポイントに対して REST または GraphQL 要求を行うことで、バックエンド コードを記述しなくてもデータを操作できます。
わかりやすくするために、このチュートリアルでは、ローカル開発の目的で Azure データベースを使用する方法について説明しますが、ローカル開発のニーズのためにローカル データベース サーバーを使用することもできます。
注意
このチュートリアルでは、Azure Database for MySQL フレキシブル サーバーを使用する方法について説明します。 別のデータベースを使用する場合は、Azure Cosmos DB、Azure SQL、または PostgreSQL のチュートリアルを参照してください。
このチュートリアルで学習する内容は次のとおりです。
- Azure Database for MySQL データベースを静的 Web アプリにリンクする
- データの作成、読み取り、更新、削除を行う
前提条件
このチュートリアルを完了するには、既存の Azure Database for MySQL と静的 Web アプリが必要です。 さらに、Azure Data Studio をインストールする必要があります。
リソース | 説明 |
---|---|
Azure Database for MySQL フレキシブル サーバー | データベースを作成する必要がある場合は、Azure Database for MySQL フレキシブル サーバーの作成に関するガイドの手順に従ってください。 Web アプリに接続文字列認証を使用する予定の場合は、必ず MySQL 認証を使用してデータベースを作成してください。 この設定は、後でマネージド ID を使用する場合、後で変更できます。 |
既存の静的 Web アプリ | まだない場合は、ファースト ステップ ガイドの手順に従って、"フレームワークなし" の静的 Web アプリを作成します。 |
Azure Data Studio と MySQL 拡張機能 | Azure Data Studio がまだインストールされていない場合は、ガイドに従って Azure Data Studio と MySQL 拡張機能をインストールします。 または、MySQL Workbench などの他のツールを使用して、MySQL データベースに対してクエリを実行することもできます。 |
まず、Azure Static Web Apps データベース接続機能を使用するようにデータベースを構成します。
データベース接続を構成する
データベース接続が機能するためには、Azure Static Web Apps がデータベースにネットワーク アクセスできる必要があります。 さらに、Azure データベースをローカル開発に使用するには、独自の IP アドレスからの要求を許可するようにデータベースを構成する必要があります。
Azure portal で、Azure Database for MySQL サーバーのフレキシブル サーバーにアクセスします。
[設定] セクションで、[ネットワーク] を選択します。
[ファイアウォール規則] セクションで、[Add your current client IP address](現在のクライアント IP アドレスの追加) ボタンを選択します。 この手順により、このデータベースをローカル開発に使用できるようになります。
[ファイアウォール規則] セクションで [Azure 内の任意の Azure サービスにこのサーバーへのパブリック アクセスを許可する] チェックボックスをオンにします。 この手順により、デプロイされた Static Web Apps リソースがデータベースにアクセスできるようになります。
[保存] を選択します。
ローカル開発用のデータベース接続文字列を取得する
Azure データベースをローカル開発に使用するには、データベースの接続文字列を取得する必要があります。 ローカル データベースを開発目的で使用する予定の場合は、この手順を省略できます。
Azure portal で、Azure Database for MySQL サーバーのフレキシブル サーバーにアクセスします。
[設定] セクションで、[接続する] を選択します。
[アプリからの接続] セクションで ADO.NET 接続文字列を選択し、テキスト エディターに貼り付けておきます。
接続文字列の
{your_password}
プレースホルダーをお使いのパスワードに置き換えます。{your_database}
プレースホルダーをデータベース名MyTestPersonDatabase
に置き換えます。 後の手順でMyTestPersonDatabase
を作成します。接続文字列の SslMode セクションと SslCa セクションを削除します。これらは追加の手順を必要とし、運用環境向けです。
サンプル データの作成
サンプル テーブルを作成し、チュートリアルと一致するサンプル データをシード処理します。 ここでは、Azure Data Studio を使用できますが、MySQL Workbench やその他のツールを使用することもできます。
Azure Data Studio で、Azure MySQL フレキシブル サーバーへの接続を作成します。
ご自分のサーバーを右クリックし、新しいデータベースを作成します。 データベース名として「
MyTestPersonDatabase
」と入力し、文字セットにutf8mb4
、照合順序にutf8mb4_0900_ai_ci
を選択します。ご自分のサーバーを右クリックし、[最新の情報に更新] を選択します。
MyTestPersonDatabase
データベースを右クリックし、[新しいクエリ] を選択します。 次のスクリプトを実行して、MyTestPersonTable
という名前の新しいテーブルを作成します。CREATE TABLE MyTestPersonTable ( Id INT AUTO_INCREMENT NOT NULL, Name VARCHAR(25) NULL, PRIMARY KEY (Id) );
次のスクリプトを実行して、
MyTestPersonTable
テーブルにデータを追加します。INSERT INTO MyTestPersonTable (Name) VALUES ('Sunny'); INSERT INTO MyTestPersonTable (Name) VALUES ('Dheeraj');
MyTestPersonTable
テーブルを右クリックして [上位 1000 を選択する] を選択し、データベースにデータがあることを確認します。
静的 Web アプリを構成する
このチュートリアルの残りの部分では、ローカルでデータベース接続を使用するように静的 Web アプリのソース コードを編集することに重点を置いています。
重要
次の手順では、ファースト ステップ ガイドで作成した静的 Web アプリを使用していることを前提としています。 別のプロジェクトを使用している場合は、ブランチ名と一致するように次の git コマンドを調整してください。
main
ブランチに切り替えます。git checkout main
git pull
を使用して、ローカル バージョンを GitHub 上のバージョンと同期します。git pull origin main
データベース構成ファイルを作成する
次に、静的 Web アプリがデータベースとのインターフェイスに使用する構成ファイルを作成します。
ターミナルを開き、接続文字列を保持する新しい変数を作成します。 具体的な構文は、使用しているシェルの種類によって異なる場合があります。
export DATABASE_CONNECTION_STRING='<YOUR_CONNECTION_STRING>'
<YOUR_CONNECTION_STRING>
を、テキスト エディターに貼り付けておいた接続文字列の値に必ず置き換えてください。npm を使用して、Static Web Apps CLI をインストールまたは更新します。 ご自分の状況に最も適したコマンドを選択します。
インストールするには、
npm install
を使用します。npm install -g @azure/static-web-apps-cli
更新するには、
npm update
を使用します。npm update
swa db init
コマンドを使用して、データベース構成ファイルを生成します。swa db init --database-type mysql
init
コマンドでは、swa-db-connections フォルダーに staticwebapp.database.config.json ファイルが作成されます。このサンプルを、生成した staticwebapp.database.config.json ファイルに貼り付けます。
{
"$schema": "https://github.com/Azure/data-api-builder/releases/latest/download/dab.draft.schema.json",
"data-source": {
"database-type": "mysql",
"options": {
"set-session-context": false
},
"connection-string": "@env('DATABASE_CONNECTION_STRING')"
},
"runtime": {
"rest": {
"enabled": true,
"path": "/rest"
},
"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": "MyTestPersonTable",
"permissions": [
{
"actions": ["*"],
"role": "anonymous"
}
]
}
}
}
次の手順に進む前に、構成ファイルのさまざまな側面について説明する次の表を確認してください。 構成ファイルに関する完全なドキュメントについては、データ API ビルダーのドキュメントを参照してください。
機能 | 説明 |
---|---|
データベース接続 | 開発時に、ランタイムによって構成ファイル内の接続文字列の値から接続文字列が読み取られます。 接続文字列は構成ファイルに直接指定できますが、ベスト プラクティスは、接続文字列をローカル環境変数に格納することです。 構成ファイル内の環境変数の値は、@env('DATABASE_CONNECTION_STRING') 表記を介して参照できます。 接続文字列の値は、データベースを接続するときに収集された情報を使用して、デプロイされたサイトの Static Web Apps によって上書きされます。 |
API エンドポイント | REST エンドポイントは、/data-api/rest を介して使用でき、GraphQL エンドポイントはこの構成ファイル内に構成されている /data-api/graphql を介して使用できます。 REST と GraphQL パスは構成できますが、/data-api プレフィックスは構成できません。 |
API セキュリティ | runtime.host.cors 設定を使用すると、API に対して要求を行うことができる許可された配信元を定義できます。 この場合、構成には開発環境が反映され、http://localhost:4280 の場所が許可リストに載せられます。 |
エンティティ モデル | 公開されるエンティティを REST API でルートとして、または GraphQL スキーマで型として定義します。 この場合、Person という名前は、エンドポイントに公開される名前であり、entities.<NAME>.source は、データベース スキーマとテーブルのマッピングです。 API エンドポイント名がテーブル名と同じである必要がないことに注意してください。 |
エンティティのセキュリティ | entity.<NAME>.permissions 配列に一覧表示されているアクセス許可ルールは、エンティティの承認設定を制御します。 ロールを使用してルートをセキュリティで保護するのと同様に、ロールを使用してエンティティをセキュリティで保護することができます。 |
注意
構成ファイルの connection-string
、host.mode
、graphql.allow-introspection
プロパティは、サイトをデプロイするときに上書きされます。 接続文字列は、Static Web Apps リソースにデータベースを接続するときに収集された認証の詳細で上書きされます。 host.mode
プロパティが production
に設定され、graphql.allow-introspection
が false
に設定されます。 これらのオーバーライドにより、開発と運用ワークロード全体で構成ファイルの一貫性が確保され、データベース接続が有効になっている 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 サイトを実行し、データベース内のデータを直接操作することができるようになりました。
データベース構成を使用して静的 Web アプリを起動します。
swa start ./src --data-api-location swa-db-connections
CLI が開始されたので、staticwebapp.database.config.json ファイルで定義されたエンドポイントを介してデータベースにアクセスできます。
http://localhost:4280/data-api/rest/<ENTITY_NAME>
エンドポイントは、データベース内のデータを操作するための GET
、PUT
、POST
、DELETE
要求を受け入れます。
http://localhost:4280/data-api/graphql
エンドポイントは、GraphQL クエリとミューテーションを受け入れます。
データを操作する
フレームワークに依存しない次のコマンドは、データベースに対して完全な CRUD 操作を実行する方法を示しています。
各関数の出力がブラウザーのコンソール ウィンドウに表示されます。
CMD/Ctrl + Shift + I キーを押して開発者ツールを開き、[コンソール] タブを選択します。
すべての項目を一覧表示する
index.html 内の script
タグ間に次のコードを追加します。
async function list() {
const endpoint = '/data-api/rest/Person';
const response = await fetch(endpoint);
const data = await response.json();
console.table(data.value);
}
次の点に注意してください。
fetch
API の既定の要求では、動詞GET
が使用されています。- 応答ペイロード内のデータは、
value
プロパティにあります。
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 |
ブラウザーに表示される内容のスクリーンショットを次に示します。
ID で取得する
index.html 内の script
タグ間に次のコードを追加します。
async function get() {
const id = 1;
const endpoint = `/data-api/rest/Person/Id`;
const response = await fetch(`${endpoint}/${id}`);
const result = await response.json();
console.table(result.value);
}
次の点に注意してください。
- エンドポイントの後に
/person/Id
が付きます。 - ID 値がエンドポイントの場所の末尾に追加されます。
- 応答ペイロード内のデータは、
value
プロパティにあります。
async function get() {
const id = 1;
const gql = `
query getById($id: Int!) {
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
タグ間に次のコードを追加します。
Static Web Apps では、PUT
と PATCH
の両方の動詞がサポートされます。 PUT
要求ではレコード全体が更新されますが、PATCH
では部分的な更新が行われます。
async function update() {
const id = 1;
const data = {
Name: "Molly"
};
const endpoint = '/data-api/rest/Person/Id';
const response = await fetch(`${endpoint}/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
const result = await response.json();
console.table(result.value);
}
次の点に注意してください。
- エンドポイントの後に
/person/Id/
が付きます。 - ID 値がエンドポイントの場所の末尾に追加されます。
- REST 動詞は、データベース レコードを更新する
PUT
です。 - 応答ペイロード内のデータは、
value
プロパティにあります。
async function update() {
const id = 1;
const data = {
Name: "Molly"
};
const gql = `
mutation update($id: Int!, $item: UpdatePersonInput!) {
updatePerson(Id: $id, item: $item) {
Id
Name
}
}`;
const query = {
query: gql,
variables: {
id: 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 = {
Name: "Pedro"
};
const endpoint = `/data-api/rest/Person/`;
const response = await fetch(endpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
const result = await response.json();
console.table(result.value);
}
次の点に注意してください。
- エンドポイントの後に
/person/
が付きます。 - REST 動詞は、データベース レコードを追加する
POST
です。 - 応答ペイロード内のデータは、
value
プロパティにあります。
async function create() {
const data = {
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 endpoint = '/data-api/rest/Person/Id';
const response = await fetch(`${endpoint}/${id}`, {
method: "DELETE"
});
if(response.ok) {
console.log(`Record deleted: ${ id }`)
} else {
console.log(response);
}
}
次の点に注意してください。
- エンドポイントの後に
/person/Id/
が付きます。 - ID 値がエンドポイントの場所の末尾に追加されます。
- REST 動詞は、データベース レコードを削除する
DELETE
です。 - 削除が成功した場合、応答ペイロードの
ok
プロパティはtrue
です。
async function del() {
const id = 3;
const gql = `
mutation del($id: Int!) {
deletePerson(Id: $id) {
Id
}
}`;
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.log(`Record deleted: ${ result.data.deletePerson.Id }`);
}
次の点に注意してください。
- GraphQL クエリで、データベースから
Id
フィールドが選択されます。 query
オブジェクトでは、GraphQL クエリがquery
プロパティ内に保持されます。- GraphQL 関数への引数値は、
query.variables
プロパティを介して渡されます。 - サーバーに渡される要求には、
query
プロパティにクエリ定義が保持されているペイロードが必要です。 - 応答ペイロード内のデータは、
data.deletePerson
プロパティにあります。
ページを更新し、[削除] ボタンを選択します。
ブラウザーのコンソール ウィンドウに、削除要求からの応答を示すテーブルが表示されるようになりました。
"削除されたレコード: 3"
ローカルでサイトを操作したので、Azure にデプロイできるようになりました。
サイトのデプロイ
このサイトを運用環境にデプロイするために必要なのは、構成ファイルをコミットし、変更をサーバーにプッシュすることだけです。
追跡するファイルの変更を追加します。
git add .
構成の変更をコミットします。
git commit -am "Add database configuration"
変更をサーバーにプッシュします。
git push origin main
静的 Web アプリにデータベースを接続する
サイトの Static Web Apps インスタンスとデータベースの間の接続を作成するには、次の手順に従います。
Azure portal で静的 Web アプリを開く
[設定] セクションで、[データベース接続] を選択します。
[運用] セクションで、[既存のデータベースのリンク] リンクを選択します。
[既存のデータベースのリンク] ウィンドウで、次の値を入力します。
プロパティ 値 データベースの種類 ドロップダウン リストからデータベースの種類を選択します。 サブスクリプション ドロップダウン リストから Azure サブスクリプションを選択します。 リソース名 目的のデータベースが含まれているデータベース サーバー名を選択します。 データベース名 静的 Web アプリにリンクするデータベースの名前を選択します。 認証の種類 [接続文字列] を選択し、MySQL のユーザー名とパスワードを入力します。 [OK] を選択します。
データベースが Static Web Apps リソースに接続されていることを確認する
静的 Web アプリにデータベースを接続し、サイトの構築が完了したら、次の手順に従ってデータベース接続を確認します。
Azure portal で静的 Web アプリを開く
[要点] セクションで、Static Web Apps リソースの [URL] を選択して、静的 Web アプリに移動します。
[一覧表示] ボタンを選択して、すべての項目を一覧表示します。
出力は、こちらのスクリーンショットのようになります。
リソースをクリーンアップする
このチュートリアルで作成したリソースを削除する場合は、データベースのリンクを解除し、サンプル データを削除する必要があります。
データベースのリンク解除: Azure portal で静的 Web アプリを開きます。 [設定] セクションで、[データベース接続] を選択します。 リンクされたデータベースの横で、[詳細の表示] を選択します。 [データベース接続の詳細] ウィンドウで、[リンク解除] ボタンを選択します。
サンプル データの削除: データベースで、
MyTestPersonTable
という名前のテーブルを削除します。