使用 Quarkus 消費 REST API

REST
Remote
0
03:03 AM · Dec 01 ,2025

1. 簡介

微服務架構通過將大型單體系統分解為更小、鬆散耦合的服務,改變了我們設計和構建應用程序的方式。這些服務主要通過 REST API 相互通信,因此理解如何有效地消費這些 API 至關重要。

Quarkus 是一個針對微服務的現代 Java 框架。

在本教程中,我們將探索如何在 Quarkus 中創建演示 REST API,並演示使用不同客户端消耗它的各種方法。 這種知識對於構建健壯和高效的微服務應用程序至關重要。

2. 創建 API

為了開始,我們需要設置一個基本的 Quarkus 應用程序並創建一個返回帖子列表的模擬 REST API。

2.1. 創建 Post 實體

我們將創建一個 Post 實體,我們的 API 將返回:

public class Post {
    public Long id;
    public String title;
    public String description;

    // getters, setters, constructors
}

2.2. 創建 Post 資源

此外,對於這個例子,我們將創建一個資源,它將以 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 在我們的新應用程序中。

2.3. 測試 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

3. 消費API與Rest客户端

Quarkus 支持 MicroProfile Rest Client,一個功能強大且類型安全的 HTTP 客户端,通過提供基於接口的方法,簡化了消費 RESTful API 的過程。

3.1. Maven 依賴

為了開始,我們需要在我們的 pom.xml 中包含 Rest Client 依賴

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

這將提供必要的組件來與 MicroProfile Rest Client 協作。

3.2. 定義客户端接口

我們將定義一個接口,代表我們想要消費的遠程 API。這個接口應該反映 API 端點的結構:

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

@RegisterRestClient 註解將此接口註冊為 REST 客户端,configKey 屬性用於將配置屬性綁定。@Path 註解指定 API 的基本路徑。

3.3. 配置

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

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

通過這樣做,我們可以輕鬆地修改 API 的基本 URL,而無需更改源代碼。此外,我們還可以更改應用程序的默認端口:

quarkus.http.port=9000

我們這樣做是因為第一個 API 在默認端口 8080 上運行。

3.4. 使用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();
    }
}

3.5. 測試應用程序

現在,一切都已設置好,我們可以測試我們的應用程序。我們可以通過運行 curl 命令來做到這一點:

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

這將返回我們的 JSON 列表中的帖子。

4. 消耗API與JAX-RS客户端API

JAX-RS 客户端 API 是 Java RESTful Web Services API (JAX-RS) 規範的一部分。它提供了一種標準、編程的方式來創建 HTTP 請求並消費 RESTful Web 服務。

4.1. 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。

4.2. 實現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>>() {});
    }
}

我們使用 Builder 模式初始化客户端,並使用基本 URL 配置目標。

4.3. 通過資源類暴露API

現在,我們只需要將服務注入到我們的資源中:


@Path("jax-rs/consume-posts")
public class PostClientResource {
    @Inject
    JaxRsPostService jaxRsPostService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Post> getJaxRsPosts() {
        return jaxRsPostService.getPosts();
    }
}

我們使用 Builder 模式初始化客户端,並使用基本 URL 配置目標。

4.4. 測試應用程序

現在我們可以使用 curl 再次測試我們的 API:


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

5. 消費 API 與 Java 11 HttpClientJava 11 引入了一個新的 HTTP 客户端 API,它提供了一種現代、異步且功能豐富的處理 HTTP 通信的方式。 java.net.http.HttpClient 類允許我們輕鬆地發送 HTTP 請求並處理響應,在這一部分,我們將學習如何做到這一點。

5.1. 創建 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 對象。

5.2. 創建資源為了使獲取的數據通過我們的應用程序可用,我們將通過資源類暴露 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

6. 結論

在本文中,我們演示瞭如何使用 Quarkus 中的 Quarkus RestClient、JAX-RS Client API 和 Java 11 HttpClient

每種方法都有其優勢:RestClient 與 Quarkus 無縫集成,JAX-RS Client API 提供靈活性,而 Java 11 的 HttpClient 則帶來 JDK 的現代功能。掌握這些技術使微服務之間的有效通信成為可能,從而使構建可擴展且高效的架構在 Quarkus 中變得更加容易。

[/content_control]

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.