You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus REST API中如何在@RequestBody的OpenAPI标签指定多实现类

问题

我有一个Quarkus REST API,接收多种JSON格式的事件并转发至Kafka主题。希望在OpenAPI契约中自动生成这些JSON的结构,无需手动编写。目前已通过@RequestBody标签指定单个实现类(如Application.class),但需同时支持CourseEnrollment.class等多种事件类型,现咨询实现方案。

当前API端点代码示例:

@POST
@Path("/student")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Student Events Service")
@Operation(summary = "Accepts student type events", description = "Accepts student type events")
@APIResponse(responseCode = "200", description = "Event sent successfully")
@APIResponse(responseCode = "400", description = "The JSON packet sent did not conform to any known message or the primary key or shared data in the packet is invalid. \n "
             + "See Response Body for detail. -  "
             + "Error code 400-1 = Bad message structure or unknown message. Log error and continue to next message - "
             + "Error code 400-2 = Bad primary key. Fix data (client or server side) and retry later - "
             + "Error code 400-3 = Invalid shared data. Fix shared data and retry later",
             content = @Content(mediaType = "application/json",
                                schema = @Schema(implementation = ErrorResponse.class)))
@APIResponse(responseCode = "500", description = "Unexpected server error. See Response Body for detail. - "
             + "Error code 500-1 = Unable to send to KAFKA, please wait and retry later - "
             + "Error code 500-2 = Unable to connect to verification database, please wait and retry later - "
             + "Error code 500-3 = General server error, Please wait and retry later",
             content = @Content(mediaType = "application/json",
                                schema = @Schema(implementation = ErrorResponse.class)))
public Response postStudentEvent(String eventJSON) {
    // 业务逻辑
}

当前仅支持单个类的@RequestBody配置:

@RequestBody(
        required = true,
        content = @Content(
          schema = @Schema(implementation = Application.class)
        )
)

需支持的两类事件类代码:

public class CourseEnrollment {
  private String eventID;
  private String eventTime;
  private String eventType;
  private String eventUserSource;
  private String externalReference1;
  private String firstName;
  private String lastName;
  private String emailAddressPrimary;
  private String emailAddressAlternate;
  private String periodStartDate;
  private String periodEndDate;
  private String intakeIntakeYearCode;
  private String programmeCode;
  // getter/setter省略
}

public class Application {
  private String eventID;
  private String eventTime;
  private String eventType;
  private String eventUserSource;
  private String eventTrigger;
  
  private ApplicationInfo applicationDetails = null;
  private Person personDetails = null;
  private School schoolDetails = null;
  // getter/setter省略
}

注:这些类均属于当前项目,外部系统生成事件JSON并发送至该REST服务,我需将其转发至本地Kafka主题。


解决方案

方案1:使用oneOf关键字实现多类型支持

直接在@Schema中通过oneOf属性指定所有支持的事件类,OpenAPI会自动生成包含所有类型结构的契约,明确说明请求体可以是这些类型中的任意一种。

修改@RequestBody配置如下:

@RequestBody(
        required = true,
        content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(
                        oneOf = {Application.class, CourseEnrollment.class},
                        description = "支持的事件类型:Application或CourseEnrollment"
                )
        )
)

方案2:抽象公共父类/接口

如果多个事件类有公共字段(比如eventID、eventTime),可以抽象出父类,让所有事件类继承它,再通过subTypes声明具体子类,契约结构会更清晰。

  1. 创建公共父类:
public abstract class BaseStudentEvent {
    private String eventID;
    private String eventTime;
    private String eventType;
    private String eventUserSource;
    // getter/setter
}
  1. 修改事件类继承父类:
public class CourseEnrollment extends BaseStudentEvent {
    // 特有字段...
}

public class Application extends BaseStudentEvent {
    // 特有字段...
}
  1. 配置@RequestBody:
@RequestBody(
        required = true,
        content = @Content(
                mediaType = MediaType.APPLICATION_JSON,
                schema = @Schema(
                        implementation = BaseStudentEvent.class,
                        subTypes = {Application.class, CourseEnrollment.class},
                        description = "支持的学生事件类型"
                )
        )
)

方案3:拆分独立端点(可选)

如果业务允许,可将不同类型的事件拆分为独立API端点,每个端点单独配置对应的请求体类型,契约更直观,但会增加端点数量。

示例:

@POST
@Path("/student/application")
@RequestBody(
        required = true,
        content = @Content(schema = @Schema(implementation = Application.class))
)
public Response postApplicationEvent(Application application) {
    // 转发到Kafka逻辑
}

@POST
@Path("/student/course-enrollment")
@RequestBody(
        required = true,
        content = @Content(schema = @Schema(implementation = CourseEnrollment.class))
)
public Response postCourseEnrollmentEvent(CourseEnrollment enrollment) {
    // 转发到Kafka逻辑
}

内容的提问来源于stack exchange,提问作者Elmar Matthee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 00:35:31