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

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

このチュートリアルでは、以下の内容を学習します。

  • Visual Studio でサーバーレス関数プロジェクトを作成する
  • 組み込みの OpenAPI 機能を使用して関数 API をローカルでテストする
  • API Management 統合を使用して、プロジェクトを Azure の関数アプリに発行する
  • 関数のアクセス キーを取得し、API Management で設定する
  • OpenAPI 定義ファイルをダウンロードする

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

Note

この記事で取り上げられている OpenAPI と API Management の統合は現在、インプロセスの C# クラス ライブラリ関数でのみサポートされています。 分離ワーカー プロセスの C# クラス ライブラリ関数と他のすべての言語ランタイムでは、代わりにポータルからの Azure API Management 統合を使う必要があります。

前提条件

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

Visual Studio の Azure Functions プロジェクト テンプレートでは、Azure の関数アプリに発行できるプロジェクトを作成します。 また、OpenAPI 定義ファイル (以前の Swagger ファイル) の生成をサポートする、HTTP によってトリガーされる関数を作成します。

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

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

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

  4. [新しい Azure Functions アプリケーションの作成] 設定で、次の表の値を使用します。

    設定 説明
    Functions worker .NET 6 この値により、OpenAPI ファイルの生成に必要な Azure Functions ランタイムのバージョン 4.x でインプロセスで実行される関数プロジェクトが作成されます。
    関数テンプレート [HTTP trigger with OpenAPI](OpenAPI を使用した HTTP トリガー) この値により、OpenAPI 定義ファイルを生成する機能を備えた、HTTP 要求によってトリガーされる関数が作成されます。
    ランタイムストレージアカウント(AzureWebJobsStorage)にAzuriteを使用する Selected このエミュレーターは、HTTP トリガー関数のローカル開発に使用できます。 Azure の関数アプリにはストレージ アカウントが必要であるため、プロジェクトを Azure に発行する際に割り当てられるか、作成されます。
    承認レベル 関数 クライアントは、Azure で実行されている場合、エンドポイントにアクセスするときにキーを指定する必要があります。 キーと承認の詳細については、「関数のアクセス キー」を参照してください。

    Azure Functions プロジェクトの設定

  5. [作成] を選択して、OpenAPI をサポートする関数プロジェクトと HTTP トリガー関数を作成します。

Visual Studio によって、プロジェクトと、Function1 という名前のクラスが作成されます。このクラスには、HTTP トリガー関数型の定型コードが含まれています。 次に、この関数テンプレート コードを独自にカスタマイズしたコードに置き換えます。

関数コードを更新する

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

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

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

Function1.cs プロジェクト ファイルで、生成されたクラス ライブラリ コードの内容を次のコードに置き換えます。

using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
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;

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

        [FunctionName("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 (ActionResult)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 インスタンスを作成します。

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

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

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

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

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

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

  2. [関数] で、 [関数]>[TurbineRepair] を選択し、 [関数キー] を選択します。

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

  3. [関数キー] で、既定値を選択し、そのをコピーします。 これで、このキーを API Management に設定できます。これにより、関数エンドポイントにアクセスできるようになります。

API Management を構成する

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

  2. API でAzure Functions> POST 実行時に OpenAPI ドキュメント を選択し、受信処理ポリシーの追加 を選択します。

    API に受信ポリシーを追加する

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

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

関数キーが設定されたので、API を呼び出し、Azure でホストされているときに動作することを確認できます。

Azure で API を確認する

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

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

    API Management API の OpenAPI テスト ページ

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

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

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

API が意図したとおりに動作する場合は、OpenAPI 定義をダウンロードできます。

    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 についてさらに学習することもできます。