【Angular/Python】API Gateway+Lambdaのレスポンスに関して

Lambdaとは

AWSが提供するサービスの一つで、プログラムをLambda関数として登録しておくことが出来ます。

登録されたLambda関数に対して、HttpリクエストでアクセスするにはAPI Gatewayの設定が必要となります。

Lambdaはサーバーレスアプリケーションの構築をサポートしています。

サーバーレスの利点としては、EC2の様にサーバーインスタンスの設定が不要なことに加えて、ハードを保持する必要が無いため、立ち上がりのサービスなどは低コストで運用することが出来ます。

Lambdaのレスポンス

「プログラムをLambda関数として登録する」と言いましたが、Lambdaの恩恵を受ける以上、一定の基準に沿ってプログラムを作成する必要があります。

その最たるものがレスポンス。

Lambdaが指定する形式で返してあげないとプログラムが動いてくれません。

Lambdaが指定するレスポンスに関しては公式ドキュメントをご参考ください。

Lambdaのレスポンスにハマった

上記ドキュメントを見ると、一見普通のHttpレスポンスに見えるのですが、実際に動かしてみるとBodyがJson形式の文字列で帰ってきました。

どういうことかというと、Jsonオブジェクトではないので適切なモデルを用意していてもマッピングされません。

あくまでBodyというキー値に、バリューとして文字列が設定されているだけです。

初めて見た時は愕然としましたね…。「そんな感じなの?」って。

Angularでの対処

私が作成したアプリケーションのクライアントはAngularで作成したので、Angularでの対処を載せておきます。

なお、Httpアクセスクラスに関してはSwaggerによってジェネレートしている前提です。

結論から言えば、インターセプターを用いて文字列になってしまっているパラメータをJsonオブジェクトへと変換しました。

コードはこんな感じ。

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      map(res => {
        if (res instanceof HttpResponse) {
          const newRes = res.clone({
            status: res.body.status,
            body: JSON.parse(res.body.body)
          });
          return newRes;
        }
      })
    );
  }

レスポンスの中身の文字列をJsonオブジェクトに変換しておくことで、適切にマッピングされるようになります。

終わりに

業務で使用しているLambdaではこんな手の込んだことをやっている様子はなかったんですが…。

うまく仕事での経験を生かせませんでしたが、自分なりにでも解決策を見つけられたのでめでたしめでたし。

もっといい方法があったら教えてください!

以上です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください