AWS Lambda Function URLs で API Gateway 設定なしで直接呼び出してみる

AWS Lambda Function URLs (関数URL) が発表されましたね。

https://aws.amazon.com/jp/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/

AWS Lambda 関数用の組み込みHTTPSエンドポイントで、API Gateway 無しでサクっと Lambda 関数を呼び出せます。ちょっと動作確認する際などに便利。上記ブログをざっくり訳して、動作を試してみたので、メモとして残しておきます。

# さっくり翻訳

AWS Lambda を使用したマイクロサービスアーキテクチャを採用して、復元力がありスケーラブルなアプリケーションを開発しましょう。これらのアプリケーションは、ビジネスロジックを実装する複数のサーバーレス機能で構成されています。各機能は、Amazon API Gateway や Application Load Balancer などのサービスを用いて、API エンドポイント、メソッド、リソースにマッピングされます。

時には作成した関数を公開するための簡単な HTTPS エンドポイントが必要な場合があり、そのためだけに Lambda 以外の追加サービスを学習、構成、操作する必要があるかもしれません。例えば、Webhook ハンドラーや単純なフォームバリデーターなど、ひとつの Lambda 関数内で実行可能なサービスを実装する場合など。

本日、Lambda Function URLs (関数URL) が一般提供されることをお知らせします。これは、任意のLambda関数にHTTPSエンドポイントを追加し、オプションでクロスオリジンリソースシェアリング(CORS)ヘッダーを構成できる新機能です。

これにより、可用性が高く、スケーラブルで安全な HTTPS サービスの構成と監視を行いながら、より重要なことに集中できます。

# Lambda 関数URL の動作

新しい関数URLを作成し、それを任意の関数にマップします。各関数 URL はグローバルに一意であり、関数のエイリアスに関連付けることができます。関数の非修飾ARNに関連付けることもでき、この場合は $LATEST バージョンが暗黙的に呼び出されます。

例えば、関数URL を $LATEST バージョンにマッピングすると、コードの更新は関数の URL を介してすぐに利用できるようになります。一方、関数のURLをエイリアスにマッピングして、新しいものを安全にデプロイできるようにすることも可能です。バージョンを作成し、いくつかの統合テストを実行し、準備ができたらエイリアスを更新します。これにより、加重トラフィックシフトと安全なデプロイを実現することもできます。

関数URL は Lambda API によってネイティブにサポートされています。 AWS マネージメントコンソール、AWS SDK、または AWS CloudFormation、AWS SAM、AWS Cloud Development Kit (CDK) のような Infrastructure as Code (IaC) ツールなどから利用を開始できます。

# Lambda 関数URL を使ってみる

新規または既存の関数に対して関数URLを構成できます。サンプルで試してみましょう。新しい関数を作成するときに、[詳細設定]で[関数のURLを有効化]をオンにします。

認証タイプとして AWS_IAM または NONE を選択できます。今回のサンプルでは HTTP ヘッダーで提供される署名に基づくカスタム認証ロジックを使用します。したがって、認証タイプに NONE を選択します。これは、Lambda がAWS IAM Sigv4 署名をチェックしないことを意味します。関数を呼び出す前に、代わりに、関数ハンドラーでカスタムヘッダーを抽出して検証し、承認を受けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/12ebf021-03d4-6b96-342a-253286da105c.png)
認証タイプに NONE を使用する場合でも、関数のリソースベースのポリシーでパブリックアクセスを明示的に許可する必要があることに注意してください。許可しない場合、認証されていないリクエストは拒否されます。AddPermission API を使用してプログラムで権限を追加することもできます。

ワンクリックで CORS を有効にすることもできます。デフォルトの CORS 構成ではすべてのオリジンが許可されます。関数の作成後、さらにきめ細かいコントロールを追加しましょう。

※ このあたりから、翻訳から外れて試してみます

まずは Hello World テンプレートで新規に関数を作成してみました。公開して数秒後、関数URL が利用可能になります。Lambda コンソールで以下の場所にありますので、コピーしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2935e8a6-67d5-0141-e629-279e44f64d68.png)
試しに、このURLにブラウザからアクセスしてみると、以下のようにHello World サンプルのメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2c3c6b30-cab7-63e5-9cb1-6b3ad8a16eee.png)

# サンプルコードを書き替えてみる

英語ブログにあるサンプルコードは部分的なものなので、動作するよう適当に書き換えたコードを用意しました。

```js:index.js
exports.handler = async (event) => {
    const method = event.requestContext.http.method;
    const queryParam = event.queryStringParameters.myCustomParameter;
    console.log(`Received ${method} request with ${queryParam}`);
    const headers = event.headers;
    const body = JSON.parse(event.body);
    
    try {
        if (headers.signatureheader !== 'XYZ') {
            throw 'Need a header: SignatureHeader';
        }
    } catch (error) {
        console.error(error)
        return {
            statusCode: 400,
            body: `Cannot process event: ${error}`,
        }
    }

    return {
        statusCode: 200,
        body: JSON.stringify({
            received: true,
        }),
    };
};
```

以下のように curl コマンドでアクセスを試してみます。これは [この投稿](https://qiita.com/yamachan360/items/8c928738289cd518eec8) にあるように、Windows のコマンドプロンプトで動作します。

```shell
curl -X POST -H "SignatureHeader: XYZ" -H "Content-type: application/json" https://ffp7f5ofpgxxxxxxxxxxxxxxxi0tqqed.lambda-url.ap-northeast-1.on.aws/?myParameter=yamachan -d "{\"type\": \"payment-succeeded\"}"
```

英語サンプルと同様、認証用のヘッダを指定しないとエラーになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a85ddfa9-1053-bc23-de14-45a33dffb126.png)
-i オプション付けてヘッダも表示させたほうが、動作を良く理解できるでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/040c4e24-b3e3-3e02-0d31-6baa2e91cfe8.png)

# というわけで

API Gateway 設定も楽しいですが、ワンクリックで自動的にエンドポイント作成してくれるのは、ちょっと試したり、他人に見てもらう際、より手軽で良いですねー。

あまりにも簡単なので英語ブログだけで情報は十分な気もしますが。まあ、久しぶりにメモ作成したので Qiita 記事として残しておきます。

それではまた。