nakamurakko’s diary

仕事で覚えたこと、勉強したことを自分のメモ代わりに書いていこうかなと。

Azure FunctionsとSQL データベースを連携する

AzureのDB「SQLデータベース」にデータ登録し、AzureのFunction Appからアクセスしてデータを返す方法の確認。

環境

SQL データベースの設定

SQL データベースを作成する

SQLデータベースで新規追加する。 テストなので、とりあえずBasic、容量100MBで契約する。

f:id:nakamurakko:20200228083004p:plain

作成後はデータアクセス出来るようにファイアウォールを設定する。

f:id:nakamurakko:20200228083119p:plain

データ追加

干支の一覧を持つテーブルを作成する。

create table zodiac_type(
    id numeric(2),
    zodiac_name nvarchar(1)
)

干支情報をINSERTする。

insert into zodiac_type(id, zodiac_name) values ( 0, '');
insert into zodiac_type(id, zodiac_name) values ( 1, '');
insert into zodiac_type(id, zodiac_name) values ( 2, '');
insert into zodiac_type(id, zodiac_name) values ( 3, '');
insert into zodiac_type(id, zodiac_name) values ( 4, '');
insert into zodiac_type(id, zodiac_name) values ( 5, '');
insert into zodiac_type(id, zodiac_name) values ( 6, '');
insert into zodiac_type(id, zodiac_name) values ( 7, '');
insert into zodiac_type(id, zodiac_name) values ( 8, '');
insert into zodiac_type(id, zodiac_name) values ( 9, '');
insert into zodiac_type(id, zodiac_name) values (10, '');
insert into zodiac_type(id, zodiac_name) values (11, '');

SQL実行はツールを使わなくても、SQLデータベース → クエリエディターで実行できる。

f:id:nakamurakko:20200228083159p:plain

Azure Functionsプロジェクトを作成する

新規作成

Visual Studioの新規プロジェクトで「Azure Functions」を選択する。

f:id:nakamurakko:20200228083230p:plain

.NET Coreを選択し、HTTP Triggerを選択する。

f:id:nakamurakko:20200228083300p:plain

NuGetからSystem.Data.SqlClientをインストール

SQLデータベースに接続するので、メニューのプロジェクトから「NuGet パッケージ」の管理を開き「System.Data.SqlClient」を追加する。 ※現段階では、Visual Studio for Macでは、System.Data.SqlClientを使ったローカルデバッグは失敗するらしい。

f:id:nakamurakko:20200228083325p:plain

Azure Functionsからアクセスする

干支の漢字を返すクラス、メソッドを用意した。

class OrientalZodiacModels
{
    /// <summary>
    /// 干支を返す。
    /// </summary>
    /// <param name="year">調べたい年。</param>
    /// <returns>干支を返す。</returns>
    public static string GetOrientalZodiac(string year)
    {
        // null、空文字の場合、入力を促す。
        if (string.IsNullOrEmpty(year))
        {
            return "入力してください。";
        }

        // 数値変換できなければ、数値入力を促す。
        var intValue = 0;
        if (!int.TryParse(year, out intValue))
        {
            return "数値を入力してください。";
        }

        // ①干支の計算
        var zodiacId = (intValue + 8) % 12;

        // ②設定の取得
        var config = new ConfigurationBuilder().AddJsonFile("local.settings.json", true).AddEnvironmentVariables().Build();
        // ③DB接続文字列の取得
        var connectionString = config.GetConnectionString("orientalzodiac");

        // ④データ取得
        using (var connection = new SqlConnection(connectionString))
        {
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandText = "select zodiac_name from zodiac_type where id=@id";
                command.Parameters.AddWithValue("@id", zodiacId);

                using (var reader = command.ExecuteReader())
                {
                    if (reader.Read())
                    {
                        return reader["zodiac_name"].ToString();
                    }
                }
            }
        }

        return "分かりません。";
    }
}
  • ①で干支の計算する。
  • ②で設定情報を取得する。
  • ③で設定情報からDB接続文字列を取得する。(今回は「orientalzodiac」で定義。)
  • ④でデータ取得する。

②、③で取得するDB接続文字列はSQLデータベースのメニュー「接続文字列」から取得できる。

f:id:nakamurakko:20200228083357p:plain

取得したDB接続文字列のID、パスワードは適宜変更して、ローカルでデバッグ実行する場合は「local.settings.json」に記載する。

{
  "ConnectionStrings": {
    "orientalzodiac": "Server=tcp:xxx.database.windows.net,1433;Initial Catalog=orientalzodiac;Persist Security Info=False;User ID=DBのID;Password=DBパスワード;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
  }
}

Function AppではAzureに登録後、アプリケーション設定 - 接続文字列を追加する。

f:id:nakamurakko:20200228083448p:plain

メインクラスから呼び出し

作成したメソッドをメインクラスから呼び出す。GETまたはPOSTで「year」を渡せば、干支の漢字を返す。

public static class FunctionOrientalZodiac
{
    [FunctionName("FunctionOrientalZodiac")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        // year(年)を取り出す。(GETの場合)
        string year = await Task<string>.Run(() => { return req.Query["year"]; });

        // year(年)を取り出す。(POSTの場合)
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        year = year ?? data?.year;

        // OrientalZodiacModels.GetOrientalZodiacは干支を返す。
        return new OkObjectResult(OrientalZodiacModels.GetOrientalZodiac(year));
    }
}

あとは、Function Appの発行でAzureにアップロードすれば、アクセスできる。