Azure Functions から Azure Database for MySQL フレキシブル サーバー へ接続

こんにちは。サイオステクノロジーの木村です。

今回は、Azure Functionsで作成したサーバレス APIから、Azure Database for MySQL フレキシブル サーバー へ接続し操作を行う方法をご紹介します。
Azure Functionsで使用する言語は JavaScript とします。

こちらは 『Visual Studio Codeを使用して、Azure Static Web Apps + Vue.js + Azure FunctionsでWebアプリ開発』 の続きの記事になります。Azure Static Web Apps + Azure Functions の環境構築をしていない方は、まずはそちらの記事を参照し環境構築を行ってください。当記事では、そちらの環境に、MySQLフレキシブル サーバーに接続する Azure Functions を作成していく手順を記載します。

Azure Database for MySQL フレキシブル サーバー の作成

まずは接続先となる Azure Database for MySQL フレキシブル サーバーを作成します。

Azure ポータルからの作成手順

1. Azureポータル(https://portal.azure.com/)にログインします。

2. 画面上部の検索欄に「Azure Database for MySQL フレキシブル サーバー」と入力して検索し、表示された「Azure Database for MySQL フレキシブル サーバー」をクリックします。

3. 「+作成」をクリックし、「フレキシブル サーバー」をクリックします。

4. 以下のように入力します。

  • サブスクリプション:任意の値
  • リソースグループ:任意の値
  • サーバ名:任意の値
  • リージョン:任意の値
  • MySQLバージョン:8.0
  • ワークロードの種類:開発プロジェクトまたは趣味プロジェクトの場合
  • 可用性ゾーン:優先設定なし
  • 高可用性:オフ
  • 認証方法:MySQL の認証のみ
  • 管理者ユーザー名:任意の値
  • パスワード:任意のパスワード(忘れないようにメモしておく)


5. 「次:ネットワーク>」をクリックします。

6. 以下のように入力します。

  • ネットワーク接続/接続方法:Public access (allowed IP addresses) and Private endpoint
  • パブリック アクセス:オン

「ファイアウォール規則」の「+現在のクライアント IP アドレスを追加する( xxx.xxx.xxx.xxx )」をクリックして、ファイアウォール規則を追加します。

7.「確認および作成」をクリックします。

8. 表示された内容を確認し「作成」をクリックします。

9. 「デプロイが完了しました」と表示されたら作成が完了です。「リソースに移動」をクリックして作成したMySQLフレキシブルサーバのリソース画面に遷移します。

10. リソース画面の概要に表示されている「サーバー名」をメモしておきます。

11. 作成したサーバにデータベースを追加します。左側のメニューより「データベース」をクリックします。

12. 「+追加」をクリックします。

13. 任意の名前を入力し、「保存」をクリックするとデータベースが作成されます。(今回の手順では、データベース名を「sample-db」とします。)

14. 次に、証明書をダウンロードします。作成したMySQLフレキシブルサーバのリソース画面を表示し、左側のメニューより「ネットワーク」をクリックします。

15.「SSL証明書のダウンロード」をクリックして、証明書をローカル環境にダウンロードしておきます。

ローカルから接続

作成した Azure Database for MySQL フレキシブル サーバーに、ローカル環境から接続してみましょう。今回は、MySQL Workbench を使用して接続する例で手順を記載します。MySQL Workbenchをインストールしていない場合は、インストールしておいてください。

1. MySQL Workbench を起動し、「+」をクリックします。

2. [Parameters]タブで以下のように入力します。

  • Connection Name:任意の名称
  • Connection Method:Standard(TCP/IP)
  • Hostname:上記、作成の手順 10. でメモしたサーバー名
  • Username:上記、作成の手順 4. で指定した管理者ユーザー名


3. [SSL]タブを選択し、以下のように入力します。

  • Use SSL:Require
  • SSL CA File:上記、作成の手順 15. でダウンロードした証明書ファイル


4. 「Test Connection」ボタンをクリックすると接続をテストすることができます。「Test Connection」ボタンをクリックすると以下のウィンドウが立ち上がりますので、上記、作成の手順 4. で指定したパスワードを入力して「OK」をクリックします。

5. 以下のメッセージが表示されれば接続テスト成功です。「OK」をクリックして画面を閉じます。

6. 作成した接続情報が MySQL Workbench 上に表示されますので、クリックし、 MySQL Workbench で Azure MySQL フレキシブル サーバーに接続します。


7. 今回のサンプル用にテーブルを作成しておきます。以下のSQLを実行し、テーブルを作成しておいてください。

CREATE TABLE `sample-db`.`fruits` (
  `id` INT NOT NULL,
  `name` VARCHAR(50) NOT NULL,
  `price` INT NOT NULL,
  PRIMARY KEY (`id`));

8. 作成したテーブルに、いくつかデータを追加しておきます。以下のSQLを実行し、レコードの追加を行ってください。

INSERT INTO `sample-db`.`fruits` (`id`, `name`, `price`) VALUES ('1', 'りんご', '100');
INSERT INTO `sample-db`.`fruits` (`id`, `name`, `price`) VALUES ('2', 'ぶどう', '500');
INSERT INTO `sample-db`.`fruits` (`id`, `name`, `price`) VALUES ('3', 'バナナ', '150');

Azure Functions の作成

MySQL へ接続し操作を行う Azure Functions を作成します。
Visual Studio Codeを使用して、Azure Static Web Apps + Vue.js + Azure FunctionsでWebアプリ開発』の記事に記載の手順で作成した Azure Static Web Apps の環境にFunctions を追加する手順で記載しますので、環境構築はそちらの手順を参照してください。Visual Studio Code にて、Azure Static Web Apps を開いておき、以下の手順を行います。

MySQL コネクタのインストール

実行環境にMySQL コネクタをイントールします。

1. Visual Studio Code の上部のメニューより、[ターミナル] – [新しいターミナル] をクリックしターミナルを開きます。

2. ターミナルにて、以下のコマンドを実行し、MySQL コネクタをインストールします。

npm install --save mysql2

Azure Functions の作成(SELECT)

MySQL へ接続し、テーブルからデータを取得する Azure Functions を作成します。

1. [表示] – [コマンド パレット] をクリックします。

2. 「Azure Static Web Apps: Create HTTP Function」と入力し表示された「Azure Static Web Apps: Create HTTP Function…」をクリックします。

3. [JavaScript]を選択します。(既に別のFunctionを作成している場合は、こちらは表示されない場合があります。)

4. [Model V3]を選択します。(既に別のFunctionを作成している場合は、こちらは表示されない場合があります。)

5. 任意の関数名を入力します。(今回の例では、「HttpTriggerSelect」という名称で作成します。)

6. アクティビティ バーの エクスプローラー ロゴをクリックします。

7. 作成された Azure Functions プロジェクトが表示されます。 既定では、リポジトリのルートにある api という名前のフォルダにプロジェクトが作成されます。

8. 作成された Azure Functions プロジェクト直下に「cert」というフォルダを作成し、certフォルダ配下に、「Azure Database for MySQL フレキシブル サーバー の作成」の手順 15. でダウンロードした証明書を配置しておきます。

9. 「index.js」を以下のように修正し、MySQLサーバーに接続して、テーブルよりデータを取得して取得した値を返すように実装します。

index.js

const mysql = require('mysql2/promise');
const fs = require('fs');
const path = require('path');

module.exports = async function (context, req) {
    const certFile = path.join(__dirname, './cert/DigiCertGlobalRootCA.crt.pem');
    try {
        const connection = await mysql.createConnection({
            host: 'MySQL サーバー名',
            user: '管理者ユーザー名',
            password: '管理者のパスワード',
            database: 'データベース名',
            port: 3306,
            ssl: {ca: fs.readFileSync(certFile)}
        });
        const [rows, fields] = await connection.execute('SELECT * FROM fruits');
        
        context.res = {
            status: 200,
            body: rows
        };
        await connection.end();
    } catch (err) {
        console.log('Error:', err);
        context.res = {
            status: 500,
            body: 'Error connecting or querying database'
        };
    }
}

Visual Studio Code で実行

作成した Azure Functions を Visual Studio Code 上で実行してみましょう。

1. 上部のメニューより、[実行]を選択して、[デバッグの開始]をクリックします。

2. ターミナルに、関数を呼び出す URL が表示されます。

3. ブラウザより、上記 URL にアクセスすると Visual Studio Code 上で Functions が実行され、MySQLから取得した値が返されるのが確認できます。

4. [実行] – [デバッグの停止]をクリックすると、実行を停止することができます。

Azure Functions 実装例(INSERT)

テーブルにレコードの挿入(INSERT)を行いたい場合は、「index.js」を以下のように実装することで行うことができます。
以下は、リクエストパラメータで指定された id・name・price の値を元に、テーブルにレコードを挿入する実装例です。

index.js

const mysql = require('mysql2/promise');
const fs = require('fs');
const path = require('path');

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    const { id, name, price } = req.query; // リクエストパラメータから値を取得

    if (!id || !name || !price) {
        context.res = {
            status: 400, 
            body: 'id and name and price are required.',
        };
        return;
    }

    const certFile = path.join(__dirname, './cert/DigiCertGlobalRootCA.crt.pem');
    try {
        const connection = await mysql.createConnection({
            host: 'MySQL サーバー名',
            user: '管理者ユーザー名',
            password: '管理者のパスワード',
            database: 'データベース名',
            port: 3306,
            ssl: {ca: fs.readFileSync(certFile)}
        });
        const [rows, fields] = await connection.execute('INSERT INTO fruits (id, name, price) VALUES  (?, ?, ?)', [id, name, price]);
        context.res = {
            status: 200,
            body: 'Record added successfully',
        };
        await connection.end();
    } catch (err) {
        console.log('Error:', err);
        context.res = {
            status: 500,
            body: 'Error connecting or querying database'
        };
    } 
}

Azure Functions 実装例(DELETE)

レコードの削除(DELETE)を行いたい場合は、「index.js」を以下のように実装することで行うことができます。
以下は、リクエストパラメータで指定された id のレコードをテーブルから削除する実装例です。

index.js

const mysql = require('mysql2/promise');
const fs = require('fs');
const path = require('path');

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    const { deleteid } = req.query; // リクエストパラメータから値を取得

    if (!deleteid) {
        context.res = {
            status: 400, 
            body: 'deleteid is required.',
        };
        return;
    }

    const certFile = path.join(__dirname, './cert/DigiCertGlobalRootCA.crt.pem');
    try {
        const connection = await mysql.createConnection({
            host: 'MySQL サーバー名',
            user: '管理者ユーザー名',
            password: '管理者のパスワード',
            database: 'データベース名',
            port: 3306,
            ssl: {ca: fs.readFileSync(certFile)}
        });
        const [rows, fields] = await connection.execute('DELETE FROM fruits WHERE id = ?', [deleteid]);
        context.res = {
            status: 200,
            body: 'Record deleted successfully',
        };
        await connection.end();
    } catch (err) {
        console.log('Error:', err);
        context.res = {
            status: 500,
            body: 'Error connecting or querying database'
        };
    } 
}

フロントエンド アプリの実装(APIの呼び出し)

実装

上記「Azure Functions の作成(SELECT)」で作成した、MySQLよりデータを取得する Azure Functions を呼び出し、画面に表形式で表示するように、フロントエンド アプリを実装してみましょう。
こちらも、『Visual Studio Codeを使用して、Azure Static Web Apps + Vue.js + Azure FunctionsでWebアプリ開発』の記事に記載の手順で作成した Azure Static Web Apps を元に変更を行います。

1. リポジトリルート/src フォルダ配下の「App.vue」を以下のように変更し、Azure Functions で作成した MySQLに接続してデータを取得する API を呼び出すようにします。呼び出した結果は表形式で表示します。

App.vue

<template>
  <div>
    <h1>商品一覧</h1>
    <table class="table-bordered">
      <thead>
        <tr>
          <th>名称</th>
          <th>価格</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="product in products" :key="product.id">
          <td>{{ product.name }}</td>
          <td>{{ product.price }}円</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      products: []
    };
  },
  mounted() {
    // APIからデータを取得するHTTPリクエストを行う
    fetch('/api/HttpTriggerSelect')
      .then(response => response.json())
      .then(data => {
        this.products = data;
      })
      .catch(error => {
        console.error('API Error:', error);
      });
  }
};
</script>
<style>
.table-bordered {
  border-collapse: collapse;
  width: 50%;
}

.table-bordered th,
.table-bordered td {
  border: 1px solid #ccc;
  padding: 8px;
  text-align: left;
}

.table-bordered th {
  background-color: #f2f2f2;
}
</style>

Visual Studio Code で実行

Visual Studio Code で、フロントエンドアプリと API を一緒に実行します。

1. 上部のメニューより、[ターミナル] – [新しいターミナル] をクリックしターミナルを開きます。

2. 以下のコマンドを実行し、アプリをビルドします。

npm run build

3. 以下のコマンドを実行し、アプリを Static Web Apps CLI で起動します。

swa start dist --api-location api
※ 起動時に以下のようなエラーが出た場合は、Visual Studio Code を一度終了して、再度起動してから、上記コマンドを実行してみてください。

・エラーメッセージ:Port 7071 is unavailable.

4. アプリには「http://localhost:4280/」でアクセスできます。ブラウザからアクセスして以下のように MySQL フレキシブルサーバーから取得したデータが表示されれば成功です。

5. CLI を停止するには、Ctrl + C キーを押します。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です