1. 引言

微服务架构彻底改变了应用设计方式,将单体系统拆分为更小、松耦合的服务。这些服务主要通过REST API通信,因此掌握高效消费API的方法至关重要。

Quarkus是专为微服务优化的现代Java框架。本教程将演示如何在Quarkus中创建模拟REST API,并通过不同客户端展示多种消费方式。这些知识对构建健壮高效的微服务应用非常关键。

2. 创建API

首先需要搭建基础Quarkus应用,创建一个返回文章列表的模拟REST API。

2.1 创建Post实体

定义API返回的Post实体类:

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")
        );
    }
}

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. 使用Rest Client消费API

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>

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 配置

application.properties中通过configKey指定基础URL:

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

这样无需修改源码即可轻松变更API基础URL。同时修改应用默认端口:

quarkus.http.port=9000

因为第一个API运行在默认端口8080上。

3.4 使用Rest Client

定义并配置Rest Client接口后,可通过@RestClient注解将其注入到Quarkus服务或资源类:

@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. 使用JAX-RS Client API消费API

JAX-RS Client API是Java RESTful Web Services规范的一部分,提供标准的编程方式创建HTTP请求和消费RESTful服务。

4.1 Maven依赖

pom.xml中添加RESTEasy Client依赖:

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

4.2 实现JAX-RS客户端

创建服务类设置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。

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();
    }
}

4.4 测试应用

使用curl测试API:

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

5. 使用Java 11 HttpClient消费API

Java 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实例和JacksonObjectMapper实例用于JSON解析。创建HttpRequest对象指定URI和HTTP方法,使用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();
    }
}

5.3 测试应用

使用curl测试应用:

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

6. 结论

本文演示了在Quarkus中使用三种方式消费REST API:

  1. Quarkus RestClient:与框架无缝集成,类型安全
  2. JAX-RS Client API:提供标准化的灵活性
  3. Java 11 HttpClient:利用JDK原生现代特性

⚠️ 踩坑提示:实际项目中需注意异常处理和连接池配置。掌握这些技术能有效实现微服务间通信,助力构建可扩展的Quarkus架构。


原始标题:How to Consume REST API in Quarkus | Baeldung