タイトルの通り、Azure Function App をインポートした API Management で API 実行時に 404 Not Found が返ってくる場合のログの追跡方法と解決策について、実際の画面出力を元に、ご紹介できればと思います。
実現したかったこと
Azure API Management へ Function App をインポートして API として公開する。下図では、Azure Web App から API Management へリクエストが行われていますが、本記事では API Management の TEST タブより、リクエストを実行して検証を行いました。

開発環境
- Azure Functions Core Tools 4.0.4426
- VSCode 1.71.0
- Azure CLI 2.40.0
発生した事象
Azure Function App を API Managment へリンク (インポート) 後、API Gateway 経由で API を実行したところ、404 Not Found エラーが発生する。
試したこと
仮説① - Azure Function App の Functions が正常動作していない?
発生した事象から API Gateway 経由だと、API が正常動作しないということが判明したので、一度 Function App 内の各 Functions を Azure Portal 上からテストすることにしました。
対象の Function App リソースを開き、ナビゲーションメニューより、関数 > 関数 を選択します。関数一覧が表示されるので、テストを実行したい関数を選択します。今回は GET リクエストをすると、JSON を返却する API ( HTTPTrigger ) をテストしたいと思います。
テスト対象の関数ページに遷移後、ナビゲーションメニューより Developer > コードとテスト を選択します。
コードとテスト ページに遷移したら、テストと実行 タブをクリックします。今回テストを実行する API は、検証のため bindngs.authLevel
を anonymous
に設定しています。(デフォルト設定では、function
になっているはずです) bindings.authLevel
については、後述します。
関数をテスト実行する際の HTTPメソッドとキーを選択して、実行ボタン を押します。
テスト実行後、正常動作していれば、HTTP応答コード 200 OK
が返却されます。
という訳で、Function App 内の Functions の問題ではないということが分かりました。
仮説② - API Managment でのテスト時に API 認証キーが設定されていない?
さきほど紹介したように、Function App 内の関数には、function.json
で bindigs.authLevel
を設定する必要があります。この authLevel
では、関数実行時の承認レベルを設定することができます。
authLevel
の設定値で、関数を実行時に必要となる API キーが異なります。3種類の承認レベルが存在し、各レベルごとに実行時に求められる承認キー (APIキー) が異なります。
|レベル | 説明 |
---|---|
anonymous | 関数実行時に APIキー は必要ありません |
function | 関数固有の APIキー が必要です (デフォルト値) |
admin | マスターキーが必要になります。 |
authLevel
を anonymouse
に設定変更し、API Gateway 側からテストを実行してみましたが、同様に 404 Not Found が返ってきました。エラー内容は 404 Not Found なので、当然の結果ではあるのですが... ログをしっかりと確認しましょう。
仮説③ - API Gateway 側の Backend 設定が間違えている?
ここで実現したかったことで記載している図を書いてみました。API Management のテストタブで実行しているため、確実に API Gateway にはリクエストが届いている。Inbound ポリシーにも、リクエストを遮断する設定はない。となると、API Gateway から Function App への リクエストURL に誤りがあるのでは?という仮説にいきつきました。しっかり読んでいたら、最初からこの仮説が立てられたのですが、API Management と Function App への理解が不明瞭だったため、少し時間がかかってしまいました。
まず、API Management のテストタブを使って、さきほどの API をログトレースします。
send ではなく Trace ボタンをクリックします。
Inbound -> Backend -> Outbaound のフェーズごとに、ログを確認することができるので、Backend を選択します。
API Gateway がテスト実行のリクエストを処理して、バックエンド (Function App) へどのようなリクエストを forward しているのかを確認することができます。
Backend service URL was changed. というメッセージと共に、Backend ランタイムURL の Prefix (URL末尾の/以下) が /a
になっていることが分かります。Function App の Prefix は host.json
で設定することができるのですが、何も設定していない場合、/api
になります。もちろん、自分で /a
を設定した記憶がないので、あれ、おかしいぞとここで気付きます。
検証用に関数の承認レベル (authLevel
) を anonymouse
に設定しているため、ブラウザで変更後の URL を実行してみると、ページが見つかりません。試しに、Function App の標準の Prefix である /api
に変更して、再度実行してみると、Web ブラウザ経由で JSON が返却されることが確認できました。
ということで、この Backend URL がどこで設定されるかについて紹介していきます。
まず、Function App をリンクした API Management リソースへ Azure Portal 上からアクセスします。ナビゲーションメニューより、APIs > Backend を選択し、対象のバックエンド画面へ遷移します。
概要ページから、さきほどログトレースで出力されていた Prefix が /a
になっているランタイムURL を見つけることができました。
ランタイムURL を変更するには、設定 > プロパティ を選択します。ランタイムURL の Prefix を /a
から /api
に変更して、保存ボタンを押します。
Backend URL を変更することで、無事 API Managmement から API を実行することができました。なぜ Prefix が /a
になってしまうのか、原因は不明なのですが、同じリソース (Function App) の再リンクを何度試しても prefix が /a
になってしまう事象が発生しました。もし同じ事象が発生した場合は、Backend の ランタイムURL を確認してみてください。