Spring Boot 2: StageName should be stripped from the path by default

オープン
#401 コメント 7 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
aws, java, spring-boot
領域
api, backend, cloud

調査の方向性

LambdaHandler とその SpringBootProxyHandlerBuilder 設定から始め、issue に示されている SAM HttpApi StageName とプロキシパスを、Spring Boot が受け取るリクエストパスと比較します。handler.stripBasePath がどのように使われているかを確認し、デフォルトでステージ名を不要にします。/dev/api/v1/some/resource のようなリクエストが 404 にならずに /api/v1/some/resource としてルーティングされれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Serverless Java Container version: 1.5.2

Implementations: Spring Boot 2

Framework version: spring-boot-starter-parent 2.3.8.RELEASE

Frontend service: AWS::Serverless::HttpApi (API Gateway HTTP)

Deployment method: SAM CLI

Scenario

Configure a simple HTTP API proxy to Lambda using Spring Boot 2, and be able to route requests that ignore the stage-name.

Expected behavior

Stage name (which is part of the path by default) is stripped before spring routes/maps to a controller.

Actual behavior

Getting 404's b/c spring is mapping <stage>/<path> vs <path>; requires my code to be 'stage-name aware'.

Steps to reproduce

event-source in sam template for AWS::Serverless::Function

      Events:
        BaseAdmin:
          Type: HttpApi
          Properties:
            ApiId: !Ref Api
            Method: any
            Path: /{proxy+}
            PayloadFormatVersion: "1.0"
            RouteSettings:
              ThrottlingBurstLimit: 100
              ThrottlingRateLimit: 100
            TimeoutInMillis: 29000

api def in sam template:

  Api:
    Type: AWS::Serverless::HttpApi
    Properties:
      FailOnWarnings: true
      StageName: dev

lambda handler

public class LambdaHandler implements RequestStreamHandler {
    private static final SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> HANDLER;

    static {
        Application.envSetup();
        try {
            HANDLER = new SpringBootProxyHandlerBuilder<AwsProxyRequest>().defaultProxy()
                                                                          .asyncInit()
                                                                          .springBootApplication(Application.class)
                                                                          .buildAndInitialize();
        } catch (ContainerInitializationException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        // Want to not need the line below uncommented to work!
        // HANDLER.stripBasePath(System.getenv("STRIP_BASE_PATH"));
    }

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        HANDLER.proxyStream(inputStream, outputStream, context);
    }
}

Full log output

Paste the full log output from the Lambda function's CloudWatch logs
dev is the stage name; the mapping is for /api/v1

DEBUG DispatcherServlet - GET "/dev/api/v1/some/resource", parameters={}
DEBUG DispatcherServlet - Exiting from "ERROR" dispatch, status 404

This isn't the worst thing ever...but it's definitely counter-intuitive to me. Would also appreciate any feedback on my solution; I did try some of the config options mentioned on the wiki page, but none of them seemed to do the trick until i found handler.stripBasePath. If there is a way to do this w/o passing in the StageName, that'd be better. Having it work by default would obviously be best.

主要言語
Java
スター
1.6k
フォーク
575
平均マージ
1日 15時間
マージ済み PR(30日)
12

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

aws/serverless-java-container のほかの issue

aws/serverless-java-container の issue をすべて見る

似ている issue

Java の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。