如何在 Quarkus 中调用 REST API

在本文中,我们演示如何使用 Quarkus RestClient、JAX-RS 客户端 API 和 Java 11 HttpClient在 Quarkus 中使用 REST API 。
每种方法都有优点:RestClient与 Quarkus 无缝集成,JAX-RS 客户端 API 提供灵活性,而 Java 11 的HttpClient带来了 JDK 的现代功能。
掌握这些技术可以实现微服务之间的有效通信,从而更轻松地在 Quarkus 中构建可扩展且高效的架构。

微服务架构将单片系统分解为更小、松散耦合的服务,彻底改变了我们设计和构建应用程序的方式。这些服务主要通过 REST API 相互通信,因此了解如何有效地使用这些 API 至关重要。

Quarkus 是一个针对微服务优化的现代 Java 框架。

在本教程中,我们将探索如何在 Quarkus 中创建虚拟 REST API,并演示使用不同客户端使用它的各种方法。这些知识对于构建强大而高效的基于微服务的应用程序至关重要。

创建 API
首先,我们需要设置一个基本的 Quarkus 应用程序并创建一个返回帖子列表的虚拟 REST API。

创建帖子实体
我们将创建一个我们的 API 将返回的Post实体:

public class Post {
    public Long id;
    public String title;
    public String description;
    // getters, setters, constructors
}

创建帖子资源
此外,对于此示例,我们将创建一个返回 JSON 格式的帖子列表的资源:

@Path("/posts")
public class PostResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Post> getPosts() {
        return Arrays.asList(
          new Post(1L,
"Post One", "This is the first post"),
          new Post(2L,
"Post Two", "This is the second post")
        );
    }
}

我们将在新的应用程序中使用该API。

测试 API
我们可以使用curl测试我们的新 API :

curl -X GET http://localhost:8080/posts

通过调用此方法,我们将获得帖子的 JSON 列表:

[
  {
    "id": 1,
   
"title": "Post One",
   
"description": "This is the first post"
  },
  {
   
"id": 2,
   
"title": "Post Two",
   
"description": "This is the second post"
  }
]

现在,此 API 已可运行,我们将看到如何在另一个 Quarkus 应用程序中使用它,而不是curl。

使用 Rest Client 调用 API
Quarkus 支持 MicroProfile Rest Client,这是一个强大且类型安全的 HTTP 客户端,它通过提供接口驱动的方法简化了 RESTful API 的使用。

Maven 依赖
首先,我们需要在pom.xml中包含Rest Client 依赖项:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-rest-client</artifactId>
    <version>3.13.3</version>
</dependency>

这将提供与 MicroProfile Rest Client 协同工作所需的组件。

定义客户端接口
我们将定义一个接口来表示我们想要使用的远程 API。此接口应反映 API 端点的结构:

@Path("/posts")
@RegisterRestClient(configKey =
"post-api")
public interface PostRestClient {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    List<Post> getAllPosts();
}

@RegisterRestClient注解将此接口注册为 REST 客户端,configKey属性用于绑定配置属性。@Path注解指定 API 的基本路径。

配置
可以使用接口中定义的configKey在application.properties文件中指定 REST 客户端的基本 URL :

quarkus.rest-client.post-api.url=http://localhost:8080

通过这样做,我们可以轻松修改 API 的基本 URL,而无需更改源代码。除此之外,我们还可以更改应用程序的默认端口:

quarkus.http.port=9000

我们这样做是因为第一个 API 在默认端口 8080 上运行。

使用 Rest 客户端
定义并配置 Rest Client 接口后,我们可以使用 @RestClient注释将其注入 Quarkus 服务或资源类。此注释告诉 Quarkus 提供使用基本 URL 和其他设置配置的指定接口的实例:

@Path("rest-client/consume-posts")
public class PostClientResource {
    @Inject
    @RestClient
    PostRestClient postRestClient;
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Post> getPosts() {
        return postRestClient.getAllPosts();
    }
}

测试应用程序
现在,一切设置完毕,我们可以测试我们的应用程序了。我们可以通过运行curl命令来做到这一点:

curl -X GET localhost:9000/rest-client/consume-posts

这应该返回我们的帖子的 JSON 列表。

使用 JAX-RS 客户端 API
JAX-RS 客户端 API 是 RESTful Web 服务的 Java API (JAX-RS) 规范的一部分。它提供了一种标准的、编程的方式来创建 HTTP 请求和使用 RESTful Web 服务。

Maven 依赖
首先,我们需要在 pom.xml 中包含RESTEasy 客户端依赖项:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-client</artifactId>
    <version>6.2.10.Final</version>
</dependency>

此依赖项引入了RESTEasy、Quarkus 使用的 JAX-RS 实现以及发出 HTTP 请求所需的客户端 API。

实现 JAX-RS 客户端
为了使用 REST API,我们将创建一个服务类,设置 JAX-RS 客户端、配置目标 URL 并处理响应:

@ApplicationScoped
public class JaxRsPostService  {
    private final Client client;
    private final WebTarget target;
    public JaxRsPostService() {
        this.client = ClientBuilder.newClient();
        this.target = client.target("http://localhost:8080/posts");
    }
    public List<Post> getPosts() {
        return target
          .request()
          .get(new GenericType<List<Post>>() {});
    }
}

我们使用构建器模式初始化客户端,并使用 API 请求的基本 URL 配置目标。

通过资源类公开 API
现在,我们需要做的就是将我们的服务注入到我们的资源中:

@Path("jax-rs/consume-posts")
public class PostClientResource {
    @Inject
    JaxRsPostService jaxRsPostService;
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Post> getJaxRsPosts() {
        return jaxRsPostService.getPosts();
    }
}

测试应用程序
现在我们可以使用curl再次测试我们的 API :

curl -X GET localhost:9000/jax-rs/consume-posts

使用 Java 11 HttpClient 的 API
Java 11 引入了一个新的 HTTP 客户端 API,它提供了一种现代、异步且功能丰富的方法来处理 HTTP 通信。java.net.http.HttpClient类允许我们轻松发送 HTTP 请求和处理响应,在本节中,我们将学习如何做到这一点。

创建HttpClient服务
此示例中不需要任何额外的依赖项,Java 11 的HttpClient是标准库的一部分。

现在,我们将创建一个管理HttpClient的服务类:

@ApplicationScoped
public class JavaHttpClientPostService {
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper;
    public JavaHttpClientPostService() {
        this.httpClient = HttpClient.newHttpClient();
        this.objectMapper = new ObjectMapper();
    }
    public List<Post> getPosts() {
        HttpRequest request = HttpRequest.newBuilder()
          .uri(URI.create("http://localhost:8080/posts"))
          .GET()
          .build();
        try {
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            return objectMapper.readValue(response.body(), new TypeReference<ArrayList<Post>>() { });
        }
        catch (IOException | InterruptedException e) {
            throw new RuntimeException(
"Failed to fetch posts", e);
        }
    }
}

在这个类中,我们初始化HttpClient实例和来自Jackson 的ObjectMapper实例,我们将使用它们将 JSON 响应解析为 Java 对象。

我们创建一个HttpRequest对象,指定 API 端点的 URI 和 HTTP 方法。之后,我们使用HttpClient实例的send()方法发送请求。我们使用BodyHandlers.ofString()处理响应,它将主体转换为字符串。我们将使用ObjectMapper将该字符串转换为我们的Post对象。

创建资源
为了使我们的应用程序能够获取到数据,我们将通过资源类公开JavaHttpClientPostService :

@Path("/java-http-client/consume-posts")
public class JavaHttpClientPostResource {
    @Inject
    JavaHttpClientPostService postService;
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Post> getPosts() {
        return postService.getPosts();
    }
}

测试应用程序
现在我们可以使用curl再次测试该应用程序:

curl -X GET localhost:9000/java-http-client/consume-posts