Azure Functions と API Management 統合を使用して Visual Studio でサーバーレス API を作成する

REST API は、多くの場合、OpenAPI 定義 (旧称 Swagger) ファイルを使用して記述されます。 このファイルには、API での操作と、API の要求と応答のデータを構造化する方法に関する情報が含まれます。

このチュートリアルでは、次の作業を行う方法について説明します。

  • Visual Studio でコード プロジェクトを作成する
  • OpenAPI 拡張機能をインストールする
  • HTTP トリガー エンドポイント (この中に OpenAPI 定義が含まれる) を追加する
  • 組み込みの OpenAPI 機能を使用して関数 API をローカルでテストする
  • プロジェクトを Azure 内の関数アプリに発行する
  • API Management 統合を有効にする
  • OpenAPI 定義ファイルをダウンロードする

作成するサーバーレス関数によって、風力タービンの緊急修理のコスト効果が高いかどうかを判断できる API が提供されます。 関数アプリと API Management インスタンスの両方を従量課金レベルで作成するので、このチュートリアルを完了するためのコストは最小限に抑えられます。

前提条件

コード プロジェクトを作成する

Visual Studio の Azure Functions プロジェクト テンプレートでは、Azure の関数アプリに発行できるプロジェクトを作成します。 また、HTTP トリガー関数の作成も、OpenAPI 定義ファイル (旧称 Swagger ファイル) の生成をサポートするテンプレートから行います。

  1. Visual Studio メニューで、 [ファイル]>[新規]>[プロジェクト] を選択します。

  2. [新しいプロジェクトの作成] の検索ボックスに「functions」と入力し、Azure Functions テンプレートを選択してから、 [次へ] を選択します。

  3. [新しいプロジェクトの構成] で、プロジェクトのプロジェクト名 (TurbineRepair など) を入力し、 [作成] を選択します。

  4. [新しい Azure Functions アプリケーションの作成] 設定で、Functions worker に対して次のいずれかのオプションを選択します。どのオプションを選択するかは、選択済みのプロセス モデルによって決まります。

    .NET 8.0 Isolated (長期サポート): C# 関数を分離ワーカー モデルで実行します。こちらが推奨されます。 詳細については、分離ワーカー モデルのガイドを参照してください。

  5. 残りのオプションについては、次の表の値を使用します。

    設定 説明
    関数テンプレート このように設定すると、トリガーのないプロジェクトが作成されるため、後で HTTP トリガー関数を追加するときにその名前をより自由に制御できます。
    ランタイムストレージアカウント(AzureWebJobsStorage)にAzuriteを使用する Selected このエミュレーターは、HTTP トリガー関数のローカル開発に使用できます。 Azure の関数アプリにはストレージ アカウントが必要であるため、プロジェクトを Azure に発行する際に割り当てられるか、作成されます。
    承認レベル 関数 クライアントは、Azure で実行されている場合、エンドポイントにアクセスするときにキーを指定する必要があります。 詳細については、「認可レベル」を参照してください。
  6. [作成] を選択して関数プロジェクトを作成します。

次に、Azure Functions 用の OpenAPI 拡張機能をインストールすることによってプロジェクトを更新します。これで、アプリ内の API エンドポイントの検出が可能になります。

OpenAPI 拡張機能をインストールする

OpenAPI 拡張機能をインストールする:

  1. [ツール] メニューで、[NuGet パッケージ マネージャー]>[パッケージ マネージャー コンソール] の順に選択します。

  2. コンソールで、次の Install-Package コマンドを実行して OpenAPI 拡張機能をインストールします。

    NuGet\Install-Package Microsoft.Azure.Functions.Worker.Extensions.OpenApi -Version 1.5.1
    

    使用する .NET のバージョンに基づいて、特定のバージョンの更新が必要になる場合があります。

これで、HTTP エンドポイント関数を追加できるようになりました。

HTTP エンドポイント関数を追加する

C# クラス ライブラリでは、関数で使用されるバインドはコード内で属性を適用するという方法で定義されます。 HTTP トリガーを持つ関数を作成する手順は次のとおりです。

  1. [ソリューション エクスプローラー] で、プロジェクト ノードを右クリックして [追加]>[新しい Azure 関数] を選びます。

  2. クラスを Turbine.cs と入力してから、[追加] を選びます。

  3. [Http トリガー] テンプレートを選択し、[承認レベル][関数] に設定してから [追加] を選択します。 HTTP トリガーを使用する新しい関数エンドポイントを定義する、Turbine.cs コード ファイルがプロジェクトに追加されます。

これで、Turbine 関数エンドポイントを実装するコードで HTTP トリガー テンプレート コードを置き換えるとともに、属性で OpenAPI を使用してエンドポイントを定義できるようになりました。

関数コードを更新する

この関数では、2 つのパラメーターを受け取る HTTP トリガーが使用されます。

パラメーター名 説明
hours タービン修復にかかる推定所要時間 (最も近い時間単位に繰り上げ)。
容量 タービンの容量 (キロワット単位)。

この関数では、修復コストと、タービンによってもたらされる 24 時間あたりの収益が計算されます。 パラメーターは、クエリ文字列または POST 要求のペイロードのいずれかで指定されます。

Turbine.cs プロジェクト ファイルの中にある、HTTP トリガー テンプレートから生成されたクラスの内容を、使用するプロセス モデルに応じて次のコードで置き換えます。

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Net;

namespace TurbineRepair
{
    public class Turbine
    {
        const double revenuePerkW = 0.12;
        const double technicianCost = 250;
        const double turbineCost = 100;

        private readonly ILogger<Turbine> _logger;

        public Turbine(ILogger<Turbine> logger)
        {
            _logger = logger;
        }

        [Function("TurbineRepair")]
        [OpenApiOperation(operationId: "Run")]
        [OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
        [OpenApiRequestBody("application/json", typeof(RequestBodyModel),
            Description = "JSON request body containing { hours, capacity}")]
        [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string),
            Description = "The OK response message containing a JSON result.")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            // Get request body data.
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic? data = JsonConvert.DeserializeObject(requestBody);
            int? capacity = data?.capacity;
            int? hours = data?.hours;

            // Return bad request if capacity or hours are not passed in
            if (capacity == null || hours == null)
            {
                return new BadRequestObjectResult("Please pass capacity and hours in the request body");
            }
            // Formulas to calculate revenue and cost
            double? revenueOpportunity = capacity * revenuePerkW * 24;
            double? costToFix = hours * technicianCost + turbineCost;
            string repairTurbine;

            if (revenueOpportunity > costToFix)
            {
                repairTurbine = "Yes";
            }
            else
            {
                repairTurbine = "No";
            };

            return new OkObjectResult(new
            {
                message = repairTurbine,
                revenueOpportunity = "$" + revenueOpportunity,
                costToFix = "$" + costToFix
            });
        }
        public class RequestBodyModel
        {
            public int Hours { get; set; }
            public int Capacity { get; set; }
        }
    }
}

この関数コードは、応急修復のコスト効果が高いかどうかを示す "Yes" または "No" のメッセージを返します。 また、タービンによって表される収益機会とタービンの修復コストも返されます。

API をローカルで実行して検証する

関数を実行する際、OpenAPI エンドポイントにより、生成されたページを使用して関数をローカルで簡単に試すことができます。 ローカルで実行する場合、関数のアクセス キーを指定する必要はありません。

  1. F5 キーを押して、プロジェクトを開始します。 Functions ランタイムをローカルで開始すると、一連の OpenAPI および Swagger エンドポイントが関数エンドポイントと共に出力に表示されます。

  2. ブラウザーで、RenderSwaggerUI エンドポイントを開きます。これは、http://localhost:7071/api/swagger/ui のようになります。 OpenAPI 定義に基づいて、ページが表示されます。

  3. [POST]>[Try out](試してみる) を選択し、クエリ パラメーターとして、または JSON 要求本文に hours および capacity の値を入力して、 [実行] を選択します。

    TurbineRepair API をテストするための Swagger UI

  4. hours に 6、capacity に 2500 のような整数値を入力すると、次の例のような JSON 応答が返されます。

    TurbineRepair 関数からの応答 JSON データ。

これで、応急修復のコスト効率性を確認する関数が作成されました。 次に、プロジェクトと API の定義を Azure に発行します。

Azure にプロジェクトを発行する

プロジェクトを発行するには、Azure サブスクリプションに関数アプリが存在する必要があります。 初めてプロジェクトを発行するときに、Visual Studio の発行機能によって、関数アプリが作成されます。 また、この関数アプリと統合される API Management インスタンスも作成され、TurbineRepair API を発行できます。

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、 [発行] を選択します。 [ターゲット][Azure] を選択し、 [次へ] を選択します。

  2. [特定のターゲット] で、 [Azure Function App (Windows)] を選択して、Windows で実行される関数アプリを作成し、 [次へ] を選択します。

  3. [Function Instance](関数インスタンス) で、 [+ 新しい Azure 関数を作成] を選択します。

    新しい関数アプリ インスタンスの作成

  4. 次の表に示されている値を使用して、新しいインスタンスを作成します。

    設定 内容
    名前 グローバルに一意の名前 新しい関数アプリを一意に識別する名前。 この名前をそのまま使用するか、新しい名前を入力します。 有効な文字は、a-z0-9- です。
    サブスクリプション 該当するサブスクリプション 使用する Azure サブスクリプション。 このサブスクリプションを承諾するか、ドロップダウン リストから新しいものを選択します。
    リソース グループ リソース グループの名前 関数アプリを作成するリソース グループ。 ドロップダウン リストから既存のリソース グループを選択するか、または [新規] を選択して新しいリソース グループを作成します。
    プランの種類 従量課金 従量課金プランで実行される関数アプリにプロジェクトを発行する場合は、関数アプリの実行に対してのみお支払いください。 他のホスティング プランでは、コストが高くなります。
    場所 サービスの場所 最寄りのリージョンまたは関数がアクセスする他のサービスの近くのリージョン内の [場所] を選択します。
    Azure Storage 汎用ストレージ アカウント Functions Runtime には Azure Storage アカウントが必須です。 [新規] を選択して汎用ストレージ アカウントを構成します。 または、ストレージ アカウントの要件を満たす既存のアカウントを選択することもできます。

    ストレージと共に Azure で新しい関数アプリを作成する

  5. [作成] を選択して、関数アプリとその関連リソースを Azure で作成します。 リソース作成のステータスがウィンドウの左下に表示されます。

  6. [Functions instance](関数インスタンス) に戻り、 [Run from package file](パッケージ ファイルから実行する) がオンになっていることを確認します。 関数アプリは、Zip Deploy を使用して、Run-From-Package モードが有効な状態でデプロイされます。 このデプロイ方法はパフォーマンスが向上するため、関数プロジェクトでの使用をお勧めします。

  7. [次へ] を選択し、 [API Management] ページで、 [+ API Management API を作成する] も選択します。

  8. 次の表の値を使用して、API Management で API を作成します。

    設定 説明
    API 名 TurbineRepair API の名前。
    サブスクリプション名 該当するサブスクリプション 使用する Azure サブスクリプション。 このサブスクリプションを承諾するか、ドロップダウン リストから新しいものを選択します。
    リソース グループ リソース グループの名前 ドロップダウン リストから、自分の関数アプリと同じリソース グループを選択します。
    API Management サービス 新しいインスタンス サーバーレス レベル内の同じ場所に新しい API Management インスタンスを作成するために [新規] を選択します。 [OK] を選択してインスタンスを作成します。

    API Management インスタンスと API を作成する

  9. [作成] を選択し、関数統合から API Management インスタンスと TurbineRepair API を作成します。

  10. [完了] を選択し、発行プロファイル作成のプロセスが完了したら [閉じる] を選択します。

  11. [発行] ページに "発行準備が完了しました" と表示されていることを確認してから、[発行] を選択します。これで、プロジェクト ファイルが含まれるパッケージが Azure 内の新しい関数アプリに展開されます。

    デプロイが完了すると、Azure の関数アプリのルート URL が [発行] タブに表示されます。

関数のアクセス キーを取得する

  1. [発行] タブで、 [ホスティング] の横にある省略記号 ( ... ) を選択し、 [Azure portal で開く] を選択します。 作成した関数アプリは、既定のブラウザー内で Azure portal で開かれます。

  2. [概要] ページ[関数] の下で、>[Turbine] を選択してから [関数キー] を選択します。

    TurbineRepair 関数のアクセス キーを取得する

  3. [関数キー] の下で、default キーの横にある "クリップボードにコピー" アイコンを選択します。 これで、API Management から関数エンドポイントにアクセスできるように、このコピーしたキーを設定できるようになりました。

API Management を構成する

  1. 関数アプリのページで、[API] を展開して [API Management] を選択します。

  2. 関数アプリがまだ新しい API Management インスタンスに接続されていない場合は、[API Management] の下でそのアプリを選択し、[API]>[OpenAPI Document on Azure Functions] を選択し、[Functions のインポート] チェック ボックスがオンであることを確認してから [API のリンク] を選択します。 インポートの対象として TurbineRepair のみが選択されていることを確認してから、[選択] を選択します。

  3. ページ上部にある [API Management に移動する] を選択し、API Management インスタンスの中の [API] を展開します。

  4. [API]>[すべての API] の下で [OpenAPI Document on Azure Functions]>[POST 実行] を選択してから、[受信処理] の下で [ポリシーの追加]>[クエリ パラメーターの設定] を選択します。

  5. [受信処理]の下、[クエリパラメータの設定]で、名前codeを入力し、[+値]を選択、コピーしたファンクションキーを貼り付けて、[保存]を選択します。 API Management は、関数エンドポイントに呼び出しを渡す際に、関数キーを含めます。

    API 受信処理ルールに関数の資格情報を提供します

これで関数キーが設定されたので、turbine API エンドポイントを呼び出して、これが Azure でホストされるときに動作することを確認できるようになりました。

Azure で API を確認する

  1. API で、 [テスト] タブ、 [POST Run](POST 実行) の順に選択し、 [要求本文]>[未フォーマット] に次のコードを入力して、 [送信] を選択します。

    {
        "hours": "6",
        "capacity": "2500"
    }
    

    API Management API の OpenAPI テスト ページ

    前と同様に、クエリ パラメーターと同じ値を指定することもできます。

  2. [送信] を選択し、HTTP 応答を表示して、API から同じ結果が返されることを確認します。

OpenAPI 定義をダウンロードする

API が意図したとおりに動作する場合は、新しいホストされる API の OpenAPI 定義を API Management からダウンロードできます。

    1. [API] で、Azure Functions OpenAPI 拡張機能 、省力記号 (...)、[エクスポート] の順に選択します。

    OpenAPI 定義のダウンロード

  1. さまざまな形式の OpenAPI ファイルを含め、API をエクスポートする手段を選択します。 Azure API Management から Power Platform に API をエクスポートすることもできます。

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

前の手順では、リソース グループ内に Azure リソースを作成しました。 これらのリソースが将来必要になると思わない場合は、リソース グループを削除してリソースを削除できます。

Azure portal メニューまたは [ホーム] ページから、 [リソース グループ] を選択します。 次に、 [リソース グループ] ページで、作成したグループを選択します。

[myResourceGroup] ページで、一覧表示されたリソースが、削除しようとするリソースであることを確認します。

[リソース グループの削除] を選択し、確認のためテキスト ボックスにグループの名前を入力して、 [削除] を選択します。

次のステップ

ここでは Visual Studio 2022 を使用して関数を作成しました。この関数は OpenAPI 拡張機能を使用しているため自己文書化されており、また API Management と統合されています。 ポータルの API Management で定義を編集できるようになります。 また、API Management についてさらに学習することもできます。