Skip to content

qaiserarbi/spring-boot-request-subtypes-validation

Repository files navigation

Spring Boot Polymorphic Request Validation

This project demonstrates how to handle subtypes of request bodies in Spring Boot with validation.
It shows how to create a base request (CreateTaskRequest) and extend it with specific subtypes (e.g., ConsultationSchedulingTaskRequest), while applying different validation rules depending on the subtype.


🚀 Features

  • Polymorphic DTOs with inheritance (CreateTaskRequestConsultationSchedulingTaskRequest)
  • Spring Validation (@Valid, @NotNull, custom constraints)
  • Factory Pattern for mapping request DTOs to Task entities
  • Example REST Controller with clean API endpoints


📝 Example DTOs

@Data
@Schema(description = "Request to create a new task")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "type",
        visible = true
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ConsultationSchedulingTaskRequest.class, name = "CONSULTATION_SCHEDULING"),
        @JsonSubTypes.Type(value = OfflineVisitSchedulingTaskRequest.class, name = "OFFLINE_VISIT_SCHEDULING"),
        @JsonSubTypes.Type(value = DocumentUploadTaskRequest.class, name = "DOCUMENT_UPLOAD"),
        @JsonSubTypes.Type(value = CreateTaskRequest.class, name = "SIMPLE")
})
public class CreateTaskRequest {
    @NotBlank(message = "Task name is required")
    @Size(min = 1, max = 200, message = "Task name must be between 1 and 200 characters")
    private String name;

    @Size(max = 500, message = "Description must not exceed 500 characters")
    private String description;


    @NotNull(message = "Task type is required")
    private TaskType type;

}

@Data
@EqualsAndHashCode(callSuper = true)
public class ConsultationSchedulingTaskRequest extends CreateTaskRequest{
    @NotNull(message = "Consultation name cannot be null")
    private String consultationName;
}

@Data
@EqualsAndHashCode(callSuper = true)
@Schema(name = "document_upload", description = "Document Upload Task Request")
public class DocumentUploadTaskRequest extends CreateTaskRequest {

    @NotBlank(message = "Report name cannot be blank")
    private String reportName;

}

@Data
@EqualsAndHashCode(callSuper = true)
@Schema(name = "consultation", description = "C")
public class EventSchedulingDetailsRequest extends CreateTaskRequest{

}

@Data
@EqualsAndHashCode(callSuper = true)
@Schema(name = "offline_visit", description = "Offline Visit Scheduling Task Request")
public class OfflineVisitSchedulingTaskRequest extends CreateTaskRequest{

    @NotBlank(message = "Visit task cannot be null")
    private String vistTask;

    private String visitSubTask;

    private String visitCustomTask;

}

🧪 Example API Usage

POST /tasks

Request Body (Simple Task):

{
  "name": "Simple Task",
  "description": "A basic task",
  "type": "SIMPLE"
}

Request Body (OfflineVisitSchedulingTaskRequest):

{
  "name": "Offline Visit Task",
  "description": "A basic task",
  "type": "OFFLINE_VISIT_SCHEDULING",
  "visitTask": "Visit Task",
  "visitSubTask": "Visit Sub Task",
  "visitCustomTask": "Visit Custom Task"
}

Request Body (EventSchedulingDetailsRequest):

{
  "name": "Event Scheduling Task",
  "description": "Schedule an event",
  "type": "CONSULTATION"
}

Request Body (DocumentUploadTaskRequest):

{
  "name": "Document Upload Task",
  "description": "Upload a document",
  "type": "DOCUMENT_UPLOAD",
  "reportName": "Report Name"
}

📌 Note

  • Uses Spring Boot 4.0.0 and Java 25
  • MongoDB is optional, but included in the example
  • Demonstrates best practices for DTO design, validation, and clean controllers

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages