chama
chama

Reputation: 6163

Hide property from Swagger conditionally?

I have a class that I am annotating with Swagger annotations for documentation of our API. One such class is used as part of the Response for two different endpoints. However, we are using @JsonView to hide some of the properties of the class for the different endpoints. When our Swagger.json is generated, the hidden properties are shown for both responses.

I was able to hide the properties completely by annotating them with @ApiModelProperty(hidden = true), however this hid them from both responses. Is there any way to use the JsonView to hide the properties only from some responses?

Upvotes: 1

Views: 4764

Answers (1)

SaleemKhair
SaleemKhair

Reputation: 531

Short answer is NO, there is no current support for conditional behaviour for ApiModelProperty.

Long answer - its quite a challenge - becauae as far as swagger/springfox issues go( #805,#563 ). seems there is support of JsonView, and this feature was added to release version 3.0.0, also seems that issue #805, is very similar to what you are facing, so its a good place to start.

It also mentions that there is a way, but it involves removing JsonView and rely on mapping DTOs to Models using mapstruct's @Mapper annotated Interfaces, which let you generate different DTO's for the same model.

And from a personal opinion, I think there should a seperation of responsibity here and have a 1:1 relationsip between DTO and request/response models or content, maybe have those specific cases be handled using plain old java way.

From top of my head assuming your usecase is for a Student object:

Absraction

public interface Student {
    int getId();
    String getName();
    String getAge();
}

Model

also acts as controller, can access the view layer and data layer

public class StudentModel implements Student {
    private int id;
    private String insuranceNumber;
    private String natSecurityNum;
    private String name;
    private String age;

    public double calculateEnrolmentFee() {
        // some database/service calls 
    }
    public StudentInfo getInfo(){
        // map model to info dto
    }
    public StudentDetails getDetails() {
       // map model to details dto
    }
   
    public void terminateEnrollment() {
        // some behaviour and state changes
    }
    // Override Student's getters
    .
    .
    .

}

View

For endpoint 1

public class StudentInfo implements Student {
    private int id;
    private String name;
    private String age;

   // Override Student's getters and add setters
    .
    .
}

For endpoint 2

public class StudentDetails implements Student {
    private int id;
    private String insuranceNumber;
    private String natSecurityNum;
    private String name;
    private String age;

    // Override Student's getters and add getter/setter based on design
    .
    .
    .
}

You can use builders aswell.

Upvotes: 1

Related Questions