サーバーレス API を使用して静的 Web アプリを作成する

ローカルで実行し、サーバーレス API を使用して静的 Web アプリを Azure にデプロイする方法について説明します。 このチュートリアルでは、最新のAzure Functions Node.js プログラミング モデルのプレビュー バージョンを使用します。 この記事ではAzure Functionsのプレビュー バージョンを使用するため、静的 Web アプリとは別のアプリとしてデプロイされます。

具体的には、次の方法を学習します。

  • Azure 関数アプリを使用して静的 Web アプリ (SWA) をローカルで実行する
  • SWA CLI を使用して、ローカル バックエンド API にフロントエンド要求をローカルにプロキシします。
  • 同じコードをリモートでデプロイして実行します。

静的 Web アプリ CLI によって提供されるフロントエンドとバックエンドエンドの間のプロキシは、次の機能を提供します。

  • React の URL では、/api/todoAPI のサーバーまたはポート番号は指定されません。 SWA CLI によってプロキシが管理されるため、この URL を使用した要求はローカルで正常に実行されます。
  • /.auth/login/<provider> にアクセス時のローカル認証エミュレーター。
  • ルートの管理と承認

このサンプルの認証

このサンプルの認証は、Azure Static Web Apps サービスのフロントエンド ユーザー向けに提供されています。

  • ログイン/ログアウト
  • パブリック コンテンツとプライベート コンテンツ

このサンプルのソース コード

このサンプルのソース コードは、サーバーレス API を使用して静的 Web アプリをビルドしてデプロイする方法を学習するためのものです。 このコードは運用環境向けではありません。

コードには、ベスト セキュリティ プラクティスに従っていないいくつかの場所があります。 たとえば、コードは を使用 console.log してブラウザー コンソールに書き込みます。

運用環境に移行するときは、organizationのセキュリティのベスト プラクティスに違反するコードを確認して削除する必要があります。

1. 開発環境を準備する

次のアカウントを作成します。

ローカル開発用コンピューターに以下をインストールします。

2. GitHub でサンプル リポジトリをフォークする

GitHub からデプロイを完了するには、サンプル リポジトリの独自のフォークが必要です。 フォーク プロセス中は、ブランチをコピー main するだけで済みます。

サンプル リポジトリをフォークします。 https://github.com/Azure-Samples/azure-typescript-e2e-apps

3. フォークされたサンプル リポジトリを複製する

  1. bash ターミナルで、 フォークしたリポジトリを ローカル コンピューターに複製します。 元のサンプル リポジトリを複製しないでください。 URL の例を次に示します。 https://github.com/YOUR-ACCOUNT-NAME/azure-typescript-e2e-apps

    git clone YOUR-FORKED-REPO-URL
    
  2. ローカル フロントエンド アプリの依存関係をインストールします。

    cd app-react-vite && npm install 
    
  3. ローカル バックエンド アプリの依存関係をインストールします。

    cd ../api-inmemory && npm install && cd ..
    

4. オプションで、ローカル アプリをビルドして実行する

サンプル リポジトリには、フロントエンド アプリとバックエンド アプリのいくつかのバージョンがあります。 次の手順では、フロントエンドの React 18 (Vite) バージョンと、 と API ルートを含むバックエンドのNode.jsバージョンの Azure Function v4 を/status/todo使用します。

  1. サンプル アプリのルートから、SWA CLI と ファイルを ./swa-cli.config.json 使用して、フロントエンド アプリとバックエンド アプリをビルドします。

    swa build
    

    各種パッケージとお使いの環境のバージョンによって発生することがあるエラーが発生した場合は、続行する前にそのエラーを修正します。 プロジェクトがローカルで正常にビルドされたことを知ってから、Azure Static Web Appsへのデプロイに進む必要があります。

  2. サンプル アプリのルートから、SWA CLI を使用してプロキシを使用してアプリを開始します。

    swa start
    
  3. bash ターミナルに次の行が表示されると、プロジェクトが正常に開始されました。

    [swa] Serving static content:
    [swa]   /workspaces/azure-typescript-e2e-apps/app-react-vite/dist
    [swa] 
    [swa] Serving API:
    [swa]   /workspaces/azure-typescript-e2e-apps/api-inmemory
    [swa] 
    [swa] Azure Static Web Apps emulator started at http://0.0.0.0:4280. Press CTRL+C to exit.
    
  4. プロキシされた URL http://localhost:4280の Web ブラウザーを開きます。 次のページが表示されます。

    認証前のローカル React アプリのスクリーンショット。

  5. SWA CLI によって提供される認証を使用してサインインできます。 このプロセスは、クラウドベースの Azure Static Web アプリでの認証をモックします。 フロントエンド コードでは、エンドポイントを /.auth/me 使用してユーザーの ID を取得します。 偽のユーザー名を入力し、残りのフィールドは変更しないでください。

    ローカル React アプリのモック認証フォームのスクリーンショット。

  6. ユーザーが認証されると、フロントエンドは API の環境変数などの 個人情報 を表示します。

    認証が完了したローカル React アプリのスクリーンショット。

    この API の Azure Function v4 アプリのソース コードは次のとおりです。

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    
    import { name, version } from '../../package.json';
    function isObject(v) {
        return '[object Object]' === Object.prototype.toString.call(v);
    };
    function sortJson(o){
        if (Array.isArray(o)) {
            return o.sort().map(sortJson);
        } else if (isObject(o)) {
            return Object
                .keys(o)
            .sort()
                .reduce(function(a, k) {
                    a[k] = sortJson(o[k]);
    
                    return a;
                }, {});
        }
        return o;
    }
    
    export async function status(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function processed request for url "${request.url}"`);
    
        const sortedEnv = sortJson(process.env);
    
        return { jsonBody: {
            name,
            version,
            env: sortedEnv,
            requestHeaders: request.headers 
        }};
    };
    
    app.http('status', {
        route: "status",
        methods: ['GET'],
        authLevel: 'anonymous',
        handler: status
    });
    
  7. パブリック セクションとプライベート セクションを展開して、API のコンテンツが表示されていることを確認します。

5. 新しいAzure Functions アプリを作成する

API で静的 Web アプリを実行する前のセクションは省略可能でした。 この記事の残りのセクションは、アプリと API を Azure クラウドにデプロイするために必要です。

Azure Functions v4 ランタイムのプレビュー バージョンを使用するには、新しいAzure Functions アプリを作成する必要があります。 また、プロキシされた API とマネージド API を使用する代わりに、API への Fetch 要求でAzure Functions アプリ URI を使用するために、静的 Web アプリを再構築して再デプロイする必要があります。

  1. Web ブラウザーで、Azure portalを開いて新しいAzure Functions アプリを作成する: 新しいアプリを作成する

  2. 関数アプリを作成するには、次の情報を使用します。

    Tab:Setting
    基本: サブスクリプション 使用するサブスクリプションを選択します。
    基本: リソース グループ などの first-static-web-app-with-api新しいリソース グループを作成します。 名前は、アプリのパブリック URL では使用されません。 リソース グループは、関連する Azure リソースのグループ化と管理に役立ちます。
    基本: インスタンスの詳細: 関数アプリ名 など、グローバルに一意の名前 swa-api を入力し、最後に 3 文字のランダムな文字を追加します (例: swa-api-123)。
    基本: インスタンスの詳細: コードまたはコンテナー [Code] を選択します。
    基本: インスタンスの詳細: ランタイム スタック [Node.js] を選択します。
    基本: インスタンスの詳細: ランタイム スタック [18LTS] を選択します。
    基本: オペレーティング システム [Linux] を選択します。
    基本: ホスティング [Consumption] を選択します。
    ストレージ: ストレージ アカウント これを変更しないでください。 関数イベントに役立つ新しい Azure Storage アカウントが作成されます。
    ネットワーク 何も変更しないでください。
    監視: Application Insights: Application Insights を有効にする [Yes] を選択します。 指定された既定の名前は変更しないでください。
    展開: GitHub Actions設定: 継続的配置 [Enable] を選択します。
    デプロイ: GitHub アカウント GitHub アカウントを選択します。
    展開: 組織 サンプル リポジトリをフォークしたときに使用した GitHub アカウントを選択します。
    デプロイ: リポジトリ フォークしたリポジトリ名 を選択します azure-typescript-e2e-apps
    デプロイ: ブランチ [main] を選択します。
    タグ 何も変更しないでください。
    確認と作成 [Create] を選択します。

    この手順では、フォークされたリポジトリに GitHub yaml ワークフロー ファイルを追加します。

  3. リソースが作成されたら、ボタンを Go to resource 選択します。

  4. [ 設定 ] -> [構成] を選択し、名前 AzureWebJobsFeatureFlags と値 EnableWorkerIndexingを指定して、Azure Function Node.js v4 ランタイムの構成設定を追加します。

  5. [保存] を選択して設定を保存します。

  6. bash ターミナルで、git を使用して、 GitHub フォークされたリポジトリからローカル コンピューターに新しい yaml ワークフロー ファイルをプルします。

    git pull origin main
    
  7. Visual Studio Code で、 にある ./.github/workflows/新しい yaml ワークフロー ファイルを開きます。

  8. 提供される 既定 のワークフロー ファイルは、関数のソース コードがリポジトリのルートにあり、リポジトリ内の唯一のアプリであることを前提としていますが、このサンプルではそうではありません。 この問題を解決するには、ファイルを編集します。 編集する行は、次の yaml ブロックで強調表示され、以下で説明します。

    # Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
    # More GitHub Actions for Azure: https://github.com/Azure/actions
    
    # Deploy Azure Functions Node.js v4 runtime
    # with api-inmemory subdir
    
    name: Azure Function App - api-inmemory
    
    on:
      push:
        branches:
          - main
        paths:
          - 'api-inmemory/**'
      workflow_dispatch:
    
    env:
      AZURE_FUNCTIONAPP_PACKAGE_PATH: 'api-inmemory' # set this to the path to your web app project, defaults to the repository root
      NODE_VERSION: '18.x' # Azure Functions v4 runtime requires 18
      VERBOSE: true # For debugging
    
    jobs:
      build-and-deploy:
        runs-on: ubuntu-latest
        steps:
          - name: 'Checkout GitHub Action'
            uses: actions/checkout@v2
    
          - name: Setup Node ${{ env.NODE_VERSION }} Environment
            uses: actions/setup-node@v1
            with:
              node-version: ${{ env.NODE_VERSION }}
    
          - name: 'Resolve Project Dependencies Using Npm'
            shell: bash
            run: |
              pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
              npm install
              npm run build --if-present
              npm run test --if-present
              popd
          - name: 'Upload artifact for deployment job' # For debugging
            uses: actions/upload-artifact@v3
            with:
              name: azure-function-v4-app
              path: |
                ${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}
                !${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}/node_modules
                !${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}/dist          
          - name: 'Run Azure Functions Action'
            uses: Azure/functions-action@v1
            id: fa
            with:
              app-name: 'swa-api' # change this to your Azure Function app name
              slot-name: 'Production'
              package: ${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}
              publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_123 }}
              scm-do-build-during-deployment: false
              enable-oryx-build: false
    
    プロパティの変更 目的
    name フォークの GitHub アクション リストで簡単に見つけられるように、名前を短くします。
    paths パス セクションを追加して、Azure Functions API コードが変更された場合にのみ実行されるようにデプロイを制限します。 ワークフロー ファイルを編集するときに、デプロイを手動でトリガーできます。
    AZURE_FUNCTIONAPP_PACKAGE_PATH ソース コードにサブディレクティブを使用する場合は、そのサブディレクトリのパスと名前である必要があります。
    VERBOSE この設定は、ビルドおよび配置プロセスのデバッグに役立ちます。
    という名前のステップ Upload artifact for deployment job この手順では、ダウンロード可能な成果物を作成します。 これは、Azure 関数にデプロイされているファイルを正確にデバッグするときに役立ちます。

    Upload artifact for deployment jobは省略可能です。 これは、Azure Functionsに展開されるファイルを理解してデバッグしたり、別の環境でそれらのファイルを使用したりするために使用されます。

  9. ファイルを保存し、git を使用して GitHub に追加、コミット、プッシュバックします。

    git add .
    git commit -m "fix the workflow for a subdir"
    git push origin main
    
  10. ブラウザーから、フォークのアクション領域で GitHub でワークフローを再実行します。

    GitHub のフォークされたリポジトリのスクリーンショット。GitHub アクションを再実行する方法が示されています。

  11. アクションが正常に完了するまで待ってから続行します。

  12. Web ブラウザーで、関数アプリの外部 API エンドポイントを使用して、アプリが正常にデプロイされたことを確認します。

    https://YOUR-FUNCTION-APP-NAME.azurewebsites.net/api/todo
    

    メモリ内データに対して返される JSON の結果は次のとおりです。

    {
        "1": "Say hello"
    }
    
  13. 関数の URL を書き留めます。 これは、次のセクションで必要になります。

  14. Azure 関数アプリがクラウドで動作していることがわかります。 次に、API を使用するためにクラウドに静的 Web アプリを作成する必要があります。

6. 新しい Azure Static Web アプリを作成する

この作成プロセスでは、同じフォークされた GitHub サンプル リポジトリが Azure にデプロイされます。 フロントエンド アプリのみを使用するようにデプロイを構成します。

  1. Azure portalを開き、Azure アカウントでサインインします:Azure portal

  2. 作成手順を完了するには、次の情報を使用します。

    Prompt 設定
    サブスクリプション 使用するサブスクリプションを選択します。
    リソース グループ を選択 Create new し、 などの first-static-web-appリソース グループの新しいを入力します。 名前は、アプリのパブリック URL では使用されません。 リソース グループは、1 つのプロジェクトに使用されるリソースをグループ化するのに役立ちます。
    ホスティング プランの種類 Free を選択
    Azure Functions and staging details (Azure Functions とステージングの詳細) 既定値は変更しないでください。 静的 Web アプリ内に Function API をデプロイしていません。
    デプロイの詳細 - ソース GitHub を選択
    デプロイの詳細 - GitHub 必要に応じて GitHub にサインインします。
    デプロイの詳細 - 組織 GitHub アカウントを選択します。
    デプロイの詳細 - リポジトリ という名前 azure-typescript-e2e-appsのフォークされたリポジトリを選択します。
    デプロイの詳細 - ブランチ ブランチを選択します main
    ビルドの詳細 - ビルド のプレゼンテーション [Custom] を選択します。
    ビルドの詳細 - アプリの場所 /app-react-vite」と入力します。
    ビルドの詳細 - Api の場所 空のままにします
    ビルドの詳細 - 出力場所 フロントエンドの出力ディレクトリの場所を入力します dist
  3. [Review + create](確認と作成) を選択し、次に [作成] を選択します。

  4. リソースが作成されたら、ボタンを Go to resource 選択します。

  5. [ 概要 ] ページで、静的 Web アプリの URL をメモします。 これは、Azure 関数の CORS 設定を設定するときに、次のセクションで必要になります。

  6. 作成プロセスでは、フォークされた GitHub リポジトリに GitHub yaml ワークフロー ファイルが作成されます。 次のコマンドを使用して、その変更をプルダウンします。

    git pull origin main
    
  7. ./.github/workflows/azure-static-web-apps-*.yml 見つかった GitHub アクションは、フロントエンド アプリのビルドとデプロイを担当します。 ファイルを編集して、クラウドベースのバックエンド API URL の環境変数を追加します。 編集する行は、次の yaml ブロックで強調表示され、yaml ブロックの下で説明されています。

    name: Azure Static Web Apps CI/CD
    
    on:
      push:
        branches:
          - main
        paths:
          - 'app-react-vite/**'
      pull_request:
        types: [opened, synchronize, reopened, closed]
        branches:
          - main
        paths:
          - 'app-react-vite/**'      
      workflow_dispatch:
    
    jobs:
      build_and_deploy_job:
        if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.action != 'closed')
        runs-on: ubuntu-latest
        name: Build and Deploy Job
        steps:
          - uses: actions/checkout@v2
            with:
              submodules: true
          - name: Build And Deploy
            id: builddeploy
            uses: Azure/static-web-apps-deploy@v1
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_DUNE_123 }}
              repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
              action: "upload"
              ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
              # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
              app_location: "/app-react-vite" # App source code path
              api_location: "" # Api source code path - optional
              output_location: "dist" # Built app content directory - optional
              ###### End of Repository/Build Configurations ######
            env: 
              VITE_BACKEND_URI: https://swa-api-123.azurewebsites.net
              VITE_CLOUD_ENV: production
    
      close_pull_request_job:
        if: github.event_name == 'pull_request' && github.event.action == 'closed'
        runs-on: ubuntu-latest
        name: Close Pull Request Job
        steps:
          - name: Close Pull Request
            id: closepullrequest
            uses: Azure/static-web-apps-deploy@v1
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_DUNE_123 }}
              action: "close"
    
    プロパティの変更 目的
    paths パス セクションを追加して、Azure Functions API コードが変更された場合にのみ実行されるようにデプロイを制限します。 ワークフロー ファイルを編集するときに、デプロイを手動でトリガーできます。
    workflow_dispatch デプロイ プロセスの学習と Vite ビルドでの問題のデバッグ中にのみを追加workflow_dispatchします。 この記事を超えてこのソース コードを続行する場合は、この行を削除します。
    if ... || github.event_name == 'workflow_dispatch' デプロイ プロセスの workflow_dispatch 学習と Vite ビルドの問題のデバッグ中にのみビルドの生成が許可されているイベントを含めます。
    env Vite を使用した静的ビルドに Azure Function API の URL を含めるために必要な環境変数を追加します。VITE_BACKEND_URLは、Azure Function アプリの URL です。 VITE_CLOUD_ENV は、 VITE_BACKEND_URL URL を使用するタイミングを示すパラメーターです。 意図しない側の影響があるため、このサンプルには NODE_ENV を使用しないでください。
  8. ファイルを保存し、git を使用して GitHub に追加、コミット、およびプッシュバックします。

    git add .
    git commit -m "fix the workflow for a subdir"
    git push origin main
    
  9. ブラウザーから、静的 Web アプリのフォークのアクション領域で GitHub でワークフローを再実行します。

  10. フロントエンド アプリは Azure にデプロイされます。 ここで、静的 Web アプリからの CORS 要求を許可するように Azure Function アプリを構成する必要があります。

7. Azure Function アプリの CORS を構成する

マネージド関数アプリではなく、別の Azure Function アプリを使用する場合は、静的 Web アプリからの要求を許可するように CORS を構成する必要があります。

  1. Azure portalで、Azure Function アプリを開きます。
  2. [ API -> CORS ] セクションで、許可されている配信元の一覧に静的 Web アプリの URL を追加します。

8. 静的 Web アプリをテストする

  1. ブラウザーで、静的 Web アプリを開きます。
  2. アプリと対話してサインインし、パブリックとプライベートの情報を表示し、もう一度サインアウトします。

9. この記事シリーズで使用されているすべてのリソースをクリーンアップする

この記事シリーズで作成したすべてのリソースをクリーンアップします。

  1. Azure portalでリソース グループを削除します。これにより、静的 Web アプリと関数アプリが削除されます。
  2. GitHub ポータルで、フォークしたリポジトリを削除します。

トラブルシューティング

このサンプルでは、 既知の問題と解決策の一覧を保持します。 問題が一覧にない場合は、 問題を開いてください。

静的 Web アプリと関数アプリのパブリック URL

静的 Web アプリの URL と関数アプリの URL は、各リソースの [概要] ページの Azure portalでいつでも確認できます。 これらの URL は既定でパブリックです。

次のステップ