サーバーレス 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. 開発環境を準備する
次のアカウントを作成します。
- Azure サブスクリプション - 無料の Azure アカウントを作成します
- GitHub アカウント - このチュートリアルでデプロイするには GitHub アカウントが必要です。
ローカルの開発用コンピューターに以下をインストールします。
- Node.js v18 以降
- Visual Studio Code (VS Code)
- Azure Static Web Apps (SWA) CLI
-g
フラグを使用してグローバルにインストール - Azure Functions Core Tools v4.0.5095+ (ローカルで実行している場合)
-g
フラグを使用してグローバルにインストールされる - TypeScript v4 以降
2. GitHub でサンプル リポジトリをフォークする
GitHub からのデプロイを完了するには、サンプル リポジトリの独自のフォークが必要です。 フォーク プロセスでは、 main
ブランチをコピーするだけで済みます。
サンプル リポジトリをフォークします: https://github.com/Azure-Samples/azure-typescript-e2e-apps
。
3. フォークされたサンプル リポジトリのクローンを作成します
bash ターミナルで、 フォークされたリポジトリ のクローンをローカル コンピュータに作成します。 元のサンプル リポジトリのクローンを作成しないでください。 URL の例は
https://github.com/YOUR-ACCOUNT-NAME/azure-typescript-e2e-apps
ですgit clone YOUR-FORKED-REPO-URL
ローカル フロントエンド アプリの依存関係をインストールします。
cd app-react-vite && npm install
ローカル バックエンド アプリの依存関係をインストールします。
cd ../api-inmemory && npm install && cd ..
4. オプション、ローカル アプリを構築して実行する
サンプル リポジトリには、フロントエンド アプリとバックエンド アプリのいくつかのバージョンが含まれています。 次の手順では、React 18 (Vite) バージョンのフロントエンドと、 /status
および /todo
API ルートを持つバックエンドの Node.js バージョンの Azure Function v4 を使用します。
サンプル アプリのルートから、SWA CLI と
./swa-cli.config.json
ファイルを使用して、フロントエンド アプリとバックエンド アプリを構築します。swa build
各種パッケージとお使いの環境のバージョンによって発生することがあるエラーが発生した場合は、続行する前にそのエラーを修正します。 Azure Static Web Apps へのデプロイに進む前に、プロジェクトがローカルで正常にビルドされたことを確認することが重要です。
サンプル アプリのルートから、SWA CLI を使用して、プロキシを使用してアプリを起動します。
swa start
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.
Web ブラウザを開いて、プロキシされた URL
http://localhost:4280
にアクセスします。 次のページが表示されます。SWA CLI によって提供される認証を使用してサインインできます。 このプロセスは、クラウドベースの Azure 静的 Web アプリでの認証を模擬します。 フロントエンド コードは、
/.auth/me
エンドポイントを使用してユーザーの ID を取得します。 偽のユーザー名を入力し、残りのフィールドは変更しないでください。ユーザーが認証されると、フロントエンドには API の環境変数などの プライベート 情報が表示されます。
この 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 });
パブリック セクションとプライベート セクションを展開すると、API からのコンテンツが表示されていることを確認できます。
5. 新しい Azure Functions アプリを作成する
API を使用して静的 Web アプリを実行する前のセクションはオプションでした。 記事の残りのセクションは、アプリと API を Azure クラウドにデプロイするために必要です。
Azure Functions v4 ランタイムの プレビュー バージョンを使用するには、新しい Azure Functions アプリを作成する必要があります。 また、プロキシされたマネージド API を使用する代わりに、API への Fetch リクエストで Azure Functions アプリ URI を使用するように、静的 Web アプリを再構築して再デプロイする必要があります。
Web ブラウザーで Azure portal を開いて、新しい Azure Functions アプリを作成します: 新しいアプリの作成
次の情報を使用して 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 ワークフロー ファイルを追加します。
リソースが作成されたら、
Go to resource
ボタンを選択します。[設定 -> 構成] を選択し、名前
AzureWebJobsFeatureFlags
と値EnableWorkerIndexing
の Azure Function Node.js v4 ランタイムの構成設定を追加します。[保存] を選択して設定を保存します。
bash ターミナルで、 git を使用して、GitHub にフォークされたリポジトリから新しい yaml ワークフロー ファイルをローカル コンピューターにプルダウンします。
git pull origin main
Visual Studio Code で、
./.github/workflows/
にある新しい yaml ワークフロー ファイルを開きます。提供されている 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 にデプロイされているかを理解してデバッグするため、またはそれらのファイルを別の環境で使用するために使用されます。ファイルを保存し、git を使用して追加、コミット、GitHub にプッシュバックします。
git add . git commit -m "fix the workflow for a subdir" git push origin main
ブラウザから、GitHub のフォークのアクション領域でワークフローを再実行します。
続行する前に、アクションが正常に完了するまで待ちます。
Web ブラウザーで、関数アプリの外部 API エンドポイントを使用して、アプリが正常にデプロイされたことを確認します。
https://YOUR-FUNCTION-APP-NAME.azurewebsites.net/api/todo
メモリ内データに対して返される JSON 結果は次のとおりです。
{ "1": "Say hello" }
関数の URL をメモしておきます。 それは次のセクションで必要になります。
Azure Function アプリがクラウドで動作していることがわかります。 次に、API を使用するためにクラウドに静的 Web アプリを作成する必要があります。
6. 新しい Azure 静的 Web アプリを作成する
この作成プロセスでは、同じフォークされた GitHub サンプル リポジトリを Azure にデプロイします。 フロントエンド アプリのみを使用するように展開を構成します。
Azure portal を開き、Azure アカウント Azure portalでサインインします。
次の情報を使用して、作成手順を完了します。
プロンプト 設定 サブスクリプション 使用するサブスクリプションを選択します。 リソース グループ 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
を入力します。[Review + create](確認と作成) を選択し、次に [作成] を選択します。
リソースが作成されたら、
Go to resource
ボタンを選択します。[概要] ページで、静的 Web アプリの URL をメモします。 これは、次のセクションで Azure 関数の CORS 設定を行うときに必要になります。
作成プロセスでは、フォークされた GitHub リポジトリに GitHub yaml ワークフロー ファイルが作成されます。 次のコマンドを使用して変更をプルダウンします。
git pull origin main
./.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 は意図しない副作用があるため、このサンプルには使用しないでください。 ファイルを保存し、git を使用して追加、コミット、GitHub にプッシュバックします。
git add . git commit -m "fix the workflow for a subdir" git push origin main
ブラウザーから、GitHub 上の静的 Web アプリのフォークのアクション領域でワークフローを再実行します。
フロントエンド アプリが Azure にデプロイされます。 次に、静的 Web アプリからの CORS 要求を許可するように Azure Function アプリを構成する必要があります。
7. Azure Function アプリの CORS を構成する
マネージド関数アプリではなく、別の Azure 関数アプリを使用する場合は、静的 Web アプリからの要求を許可するように CORS を構成する必要があります。
- Azure portal で、Azure Function アプリを開きます。
- API -> CORS セクションで、静的 Web アプリの URL を許可されたオリジンのリストに追加します。
8. 静的 Web アプリをテストする
- ブラウザーで静的 Web アプリを開きます。
- アプリを操作してサインインし、公開情報と個人情報を表示し、再度サインアウトします。
9. この記事シリーズで使用したすべてのリソースをクリーンアップする
この記事シリーズで作成したすべてのリソースをクリーンアップします。
- Azure portal でリソース グループを削除すると、静的 Web アプリと関数アプリが削除されます。
- GitHub ポータルで、フォークされたリポジトリを削除します。
トラブルシューティング
このサンプルには、 既知の問題と解決策のリストが保存されています。 問題がリストにない場合は、 問題を開いてください。
静的 Web アプリと関数アプリのパブリック URL
静的 Web アプリの URL と関数アプリの URL は、Azure portal の各リソースの [概要] ページでいつでも見つけることができます。 これらの URL はデフォルトで公開されています。