TL;DR: 在 Quarkus 中使用 SmallRye OpenAPI 就像拥有一个超级聪明的实习生,他在你编写代码时自动撰写和更新 API 文档。让我们深入了解如何实现这种魔法吧!

1. OpenAPI 的意义和原因:因为“它能用”还不够

在深入探讨之前,让我们先聊聊为什么我们要费心去做 API 文档。当然,你可以让用户自己“摸索”,但这就像用巧克力做的茶壶一样没用。

OpenAPI(以前称为 Swagger)是描述 RESTful API 的最佳选择。它是一种规范,允许你描述整个 API,包括:

  • 可用的端点和操作
  • 输入和输出的操作参数
  • 认证方法
  • 联系信息、许可证、使用条款和其他信息

为什么要费心呢?想象一下,没有文档的 API,就像没有说明书的宜家家具——理论上可能,但很可能以泪水和一堆奇形怪状的木头告终。

2. SmallRye OpenAPI 和 Quarkus:开发者的天堂组合

SmallRye OpenAPI 是 Quarkus 的得力助手。它是 OpenAPI 规范的一个实现,与 Quarkus 无缝集成,允许你从代码中自动生成 OpenAPI 文档。

以下是这个组合成为你 API 所需超级英雄团队的原因:

  • 从 Quarkus 代码自动生成 OpenAPI 规范
  • 基于注解的自定义,提供细粒度控制
  • 与 Swagger UI 集成,提供交互式 API 文档
  • 轻量且快速,就像 Quarkus 中的其他一切

3. 设置 SmallRye OpenAPI:更少设置,更多编码

准备好为你的 Quarkus 项目添加一些 SmallRye 魔法了吗?让我们开始吧!

首先,将以下依赖项添加到你的 pom.xml 中:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>

就是这样。真的。Quarkus 会自动检测并配置 SmallRye OpenAPI。但如果你想展示你的配置技能,可以在 application.properties 中添加一些属性:

quarkus.smallrye-openapi.path=/openapi
quarkus.swagger-ui.always-include=true

这将设置 OpenAPI 文档的路径,并确保 Swagger UI 始终包含在内,即使在生产环境中也是如此。因为谁不想在生产环境中探索 API 呢?(安全团队,别紧张,我们只是开玩笑……大部分时间是。)

4. 注解你的 API:让你的代码会说话

现在到了有趣的部分——为你的 API 添加注解以生成丰富的信息文档。SmallRye OpenAPI 使用标准的 JAX-RS 注解和 OpenAPI 特定的注解来描述你的 API。

让我们看一个例子:

import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;

@Path("/api/books")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Book Resource", description = "Book operations")
public class BookResource {

    @GET
    @Operation(summary = "Get all books", description = "Returns a list of all books")
    @APIResponse(responseCode = "200", description = "Successful operation",
                 content = @Content(mediaType = "application/json",
                 schema = @Schema(implementation = Book.class)))
    public List<Book> getAllBooks() {
        // Implementation
    }

    @POST
    @Operation(summary = "Create a book", description = "Creates a new book")
    @APIResponse(responseCode = "201", description = "Book created",
                 content = @Content(mediaType = "application/json",
                 schema = @Schema(implementation = Book.class)))
    public Response createBook(Book book) {
        // Implementation
    }
}

在这个例子中,我们使用了 @Operation@APIResponse@Tag 等注解来提供关于端点的详细信息。这些注解将被 SmallRye OpenAPI 识别并用于生成全面的文档。

5. 生成 OpenAPI 规范:魔法发生的地方

在你的代码添加注解后,SmallRye OpenAPI 将自动生成 JSON 和 YAML 格式的 OpenAPI 规范。你可以在以下位置访问这些规范:

  • /openapi(或你的自定义路径)获取 OpenAPI 文档
  • /q/openapi 获取生成的 YAML 格式的 OpenAPI 文档
  • /q/openapi?format=json 获取 JSON 格式

这些规范是你的 API 消费者的金票。他们可以用这些来生成客户端代码、设置自动化测试,或者简单地了解如何与 API 交互。

6. Swagger UI:让你的 API 互动起来

还记得我们之前启用了 Swagger UI 吗?现在是收获成果的时候了。启动你的 Quarkus 应用程序并导航到 /q/swagger-ui。瞧!你会看到一个美丽的、互动的 API 表示。

Swagger UI 允许用户:

  • 探索 API 的端点
  • 查看请求/响应模型
  • 直接从浏览器尝试 API 调用

这就像是你的 API 的游乐场,开发者可以在将其集成到他们的应用程序之前先试用一下。

7. SmallRye OpenAPI 的高级功能:提升你的文档

SmallRye OpenAPI 不仅仅是关于基本文档。它还为更高级的用例提供了一些技巧:

自定义模式

有时,你需要描述复杂的数据结构。使用 @Schema 注解来提供关于模型的详细信息:

@Schema(description = "Represents a book in the library")
public class Book {
    @Schema(description = "Unique identifier of the book", example = "123e4567-e89b-12d3-a456-426614174000")
    private UUID id;

    @Schema(description = "Title of the book", example = "The Hitchhiker's Guide to the Galaxy")
    private String title;

    // Other fields and methods
}

安全方案

使用 @SecurityScheme 注解描述你的 API 的安全要求:

@SecurityScheme(securitySchemeName = "bearerAuth",
               type = SecuritySchemeType.HTTP,
               scheme = "bearer",
               bearerFormat = "JWT")
@ApplicationPath("/api")
public class RestApplication extends Application {
    // Application configuration
}

请求/响应示例

提供示例请求和响应,使你的 API 更加用户友好:

@POST
@Operation(summary = "Create a book")
@APIResponse(responseCode = "201",
             description = "Book created",
             content = @Content(mediaType = "application/json",
                                schema = @Schema(implementation = Book.class),
                                examples = @ExampleObject(name = "book",
                                                         value = "{\"id\":\"123e4567-e89b-12d3-a456-426614174000\",\"title\":\"New Book\"}")))
public Response createBook(Book book) {
    // Implementation
}

8. 版本化你的 API:因为变化是唯一的不变

API 会演变,SmallRye OpenAPI 在版本控制方面为你提供了支持。你可以使用 @Version 注解来指定 API 的不同版本:

@Path("/api/v1/books")
@Version("1.0")
public class BookResourceV1 {
    // V1 endpoints
}

@Path("/api/v2/books")
@Version("2.0")
public class BookResourceV2 {
    // V2 endpoints
}

这允许你为 API 的不同版本维护单独的文档,确保用户无论使用哪个版本都能获得准确的信息。

9. 测试你的 OpenAPI 规范:信任,但要验证

优秀的文档只有在准确时才是优秀的。Quarkus 使得测试你的 OpenAPI 规范以确保它们与实际实现相匹配变得容易。

以下是一个简单的测试来验证你的 OpenAPI 文档:

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.containsString;

@QuarkusTest
public class OpenApiTest {

    @Test
    public void testOpenApiEndpoint() {
        given()
            .when().get("/openapi")
            .then()
                .statusCode(200)
                .body(containsString("openapi: 3.0.3"))
                .body(containsString("/api/books"));
    }
}

这个测试确保你的 OpenAPI 端点是可访问的,并包含预期的内容。你可以扩展这个测试以检查特定的操作、模式或 API 文档的其他元素。

10. 总结:为什么 SmallRye OpenAPI 是你新的好朋友

到现在,你应该相信 SmallRye OpenAPI 就像是一个随叫随到的文档精灵。让我们回顾一下为什么它是 Quarkus 开发者的游戏规则改变者:

  • 所需设置最少——几乎是即插即用
  • 自动生成全面的 API 文档
  • 通过 Swagger UI 提供交互式探索
  • 支持复杂 API 的高级功能
  • 与 Quarkus 生态系统无缝集成

有了 SmallRye OpenAPI,你可以专注于构建出色的 API,而它负责文档的繁重工作。你的未来自我(以及你的 API 消费者)会感谢你。

“好的文档就像是给试图使用你 API 的开发者的温暖拥抱。” - 可能是某位聪明的程序员

所以,去吧,为你的端点添加注解,让 SmallRye OpenAPI 将你的 Quarkus 项目变成一个文档齐全的 API 荣耀灯塔。你的用户会赞美你,你的团队会更高效地工作,你甚至可能会享受编写文档。(好吧,最后一点我们就不多说了。)

进一步阅读和资源

想更深入地了解 SmallRye OpenAPI 和 Quarkus 的世界吗?查看这些资源:

祝编码愉快,愿你的 API 永远文档齐全!