【问题标题】:AWS Lambda in Java: how to call a REST endpoint exposed in API GatewayJava 中的 AWS Lambda:如何调用 API Gateway 中公开的 REST 端点
【发布时间】:2020-12-01 08:17:54
【问题描述】:

我代表 API Gateway 在 AWS 基础设施上公开了一个 REST API。在 Java 的 Lambda 函数中,我需要调用关联的端点。 AWS 文档建议使用 API Gateway 控制台生成客户端。但是,生成的客户端有几十个类,甚至可能有 100 个!当然,这不可能。

是否有人成功使用 RESTeasy 或 CXF 客户端调用 API Gateway 公开的端点?甚至是 Apache HTTP 客户端?

非常感谢。

【问题讨论】:

  • 这更像是一个讨论而不是一个问题。我建议使用 Lambda 代理集成,而不是现在从 API Gateway 调用 Lambda 函数的“传统”方式。这样您就可以在自己的代码中执行路径(端点)处理逻辑。是一次更好的体验。
  • 您只是使用 Swagger 定义来生成 Java 客户端吗?我有点困惑,因为这与 Lambda 或 API 网关无关。一个高度复杂的 API 可能确实会生成 100 多个类,但通常设计良好的 API 应该少得多,无论实现环境如何。
  • @BjörnRaupach 你不明白这个问题。我不从 API Gateway 调用 Lambda 函数,但相反,我从 Lamda 函数调用通过 API Gateway 公开的端点。请确保您理解您要回答的问题:-)
  • @stdunbar:既然你很困惑,我会再解释一次。这与 swagger 没有任何关系,我不知道您从哪里看到任何对 swagger 的引用。 API Gateway 控制台有一个专门的功能,能够为暴露的端点生成客户端。您可以选择所需的语言并下载包含 100 个类的 Java 存档。在我看来,这个存档不仅包含调用 API 的客户端,还包含许多其他你不需要的东西,这使得这个“客户端”无法使用。因此我的问题是:有人为此目的使用 Resteasy 或 CXF 吗?

标签: aws-lambda aws-api-gateway resteasy cxf-client


【解决方案1】:

我正在回答我自己的问题。最后,我确认使用 JAX-RS 客户端可以按预期与 API 网关一起工作。就我而言,我更喜欢 RESTeasy,但它也应该可以与 CXF 一起使用,甚至可以与 Apache HTTp 客户端一起使用。这是我所做的:

Maven 依赖:

  ...
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-bom</artifactId>
        <version>4.4.1.Final</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  ...
  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-client</artifactId>
    <version>4.4.1.Final</version>
    <exclusions>
      <exclusion>
        <groupId>org.jboss.spec.javax.xml.bind</groupId>
        <artifactId>jboss-jaxb-api_2.3_spec</artifactId>
      </exclusion>
      <exclusion>
        <groupId>com.sun.activation</groupId>
        <artifactId>jakarta.activation</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxb-provider</artifactId>
    <exclusions>
      <exclusion>
        <groupId>org.jboss.spec.javax.xml.bind</groupId>
        <artifactId>jboss-jaxb-api_2.3_spec</artifactId>
      </exclusion>
      <exclusion>
        <groupId>com.sun.activation</groupId>
        <artifactId>jakarta.activation</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson2-provider</artifactId>
  </dependency>
  ...

请注意用于解决 maven-shade-plugin 的排除项,这将重载相同工件的不同版本。

maven-shade-plugin 配置:

...
<plugin>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.2.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <finalName>...</finalName>
    <createDependencyReducedPom>false</createDependencyReducedPom>
      <!-- Using filtering in order to get rid of nasty warnings generated by shading module-info-->
      <filters>
        <filter>
          <artifact>*:*</artifact>
          <excludes>
            <exclude>module-info.class</exclude>
          </excludes>
        </filter>
      </filters>
      <!-- Required as per https://stackoverflow.com/questions/24023155-->
      <transformers>
        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
        </transformers>
      </configuration>
    </plugin>
    ...

Java 客户端代码:

...
private static ResteasyClient client =  new ResteasyClientBuilderImpl().httpEngine(new URLConnectionEngine()).build();
private static WebTarget webTarget = client.target("https://...");
...
webTarget.request().post(Entity.entity(..., "application/json"));
...

请注意使用 JAX-RS 纯客户端如下:

...
private static Client client = ClientBuilder.newClient();
...

不起作用,会引发以下异常:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7933f1c0: Failure in SSL library, usually a protocol error

因此,为了解决这个问题,我需要使用 RESTeasy(非 JAX-RS)特定的东西,这并不好。这是一个 RESTeasy 错误,应该已在 4.5 中解决。但是,由于一些弃用和重构(类 ResteasyClientBuilderImpl 不再存在等),我更喜欢使用 4.4。

因此,这样做可以按预期工作,Lambda 函数成功调用通过 API Gateway 公开的 REST 端点,我不需要使用 AWS 控制台生成的庞大 Java 库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-21
    • 2020-04-21
    • 2017-12-07
    • 2017-09-19
    • 2021-01-10
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    相关资源
    最近更新 更多