次の方法で共有


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

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

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

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

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

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

このサンプルの認証

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

  • ログイン/ログアウト
  • 公開コンテンツと非公開コンテンツ

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

このサンプルのソース コードは、サーバーレス API を使用して静的 Web アプリを構築およびデプロイする方法を学習することを目的としています。 このコードは実稼働用ではありません。

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

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

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) バージョンのフロントエンドと、 /status および /todo API ルートを持つバックエンドの Node.js バージョンの Azure Function v4 を使用します。

  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. Web ブラウザを開いて、プロキシされた URL http://localhost:4280にアクセスします。 次のページが表示されます。

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

  5. SWA CLI によって提供される認証を使用してサインインできます。 このプロセスは、クラウドベースの Azure 静的 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 への Fetch リクエストで Azure Functions アプリ URI を使用するように、静的 Web アプリを再構築して再デプロイする必要があります。

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

  2. 次の情報を使用して Function App を作成します。

    タブ:設定 Value
    Basics: サブスクリプション 使用するサブスクリプションを選択します。
    Basics: リソースグループ first-static-web-app-with-api などの新しいリソース グループを作成します。 この名前はアプリのパブリック URL では使用されません。 リソース グループは、関連する Azure リソースをグループ化して管理するのに役立ちます。
    Basics: インスタンスの詳細: Function App 名 swa-api などのグローバルに一意な名前を入力し、最後に swa-api-123などの 3 つのランダムな文字を追加します。
    Basics: インスタンスの詳細: コードまたはコンテナー [Code] を選択します。
    Basics: インスタンスの詳細: ランタイムスタック [Node.js] を選択します。
    Basics: インスタンスの詳細: ランタイムスタック [18LTS] を選択します。
    Basics: オペレーティング システム [Linux] を選択します。
    Basics: Hosting [Consumption] を選択します。
    ストレージ: ストレージ アカウント これを変更しないでください。 関数イベントを支援するために、新しい Azure ストレージ アカウントが作成されます。
    ネットワーク 何も変更しないでください。
    監視: Application Insights: Application Insights を有効にする [Yes] を選択します。 指定されたデフォルトの名前は変更しないでください。
    デプロイメント: GitHub アクション設定: 継続的デプロイメント [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. 提供されている default ワークフロー ファイルでは、関数のソース コードがリポジトリのルートにあり、それがリポジトリ内の唯一のアプリであると想定されていますが、このサンプルではそうではありません。 これを修正するには、ファイルを編集します。 編集する行は、次の 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 Function アプリがクラウドで動作していることがわかります。 次に、API を使用するためにクラウドに静的 Web アプリを作成する必要があります。

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

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

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

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

    プロンプト 設定
    サブスクリプション 使用するサブスクリプションを選択します。
    リソース グループ Create new を選択し、リソース グループに新しい名前 (first-static-web-appなど) を入力します。 この名前はアプリのパブリック URL では使用されません。 リソース グループは、単一のプロジェクトに使用されるリソースをグループ化するのに役立ちます。
    ホスティング プランの種類 Free を選択
    Azure Functions and staging details (Azure Functions とステージングの詳細) デフォルトを変更しないでください。 Function API を静的 Web アプリ内にデプロイしていません。
    導入の詳細 - ソース 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' 導入プロセスを学習し、Vite ビルドの問題をデバッグする場合にのみ、ビルドの生成を許可する workflow_dispatch イベントを含めます。
    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. ブラウザーから、GitHub 上の静的 Web アプリのフォークのアクション領域でワークフローを再実行します。

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

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

マネージド関数アプリではなく、別の Azure 関数アプリを使用する場合は、静的 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 はデフォルトで公開されています。

次のステップ