I've a Java project that uses Spring Boot and Swagger. The project consists of a simple API controller that implements a single endpoint. Invoking the GET
method on the endpoint gets all users. Invoking the PUT
method on the same endpoint updates a single user:
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@RequestMapping(value = "", method = RequestMethod.GET)
public List<BaseUser> getUsers(String name) {
return null;
}
@RequestMapping(value = "", method = RequestMethod.PUT)
public BaseUser updateUser(@RequestBody BaseUser user) {
return null;
}
}
The /api/v1/users
endpoint is implemented using a BaseUser
which has subtypes like EmployeeUser
:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = EmployeeUser.class, name = "employee")
})
public abstract class BaseUser {
private final int id;
private final String name;
@JsonCreator
protected BaseUser(
@JsonProperty("id") int id,
@JsonProperty("name") String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
public class EmployeeUser extends BaseUser {
public EmployeeUser(@JsonProperty("id") int id,
@JsonProperty("name") String name) {
super(id, name);
}
}
With this structure, when I browse the Swagger UI I see duplicates of these model types (based on the definitions in the OpenAPI spec).
I expected to see only a single BaseUser
and a single EmployeeUser
. What is the reason for the duplicates?
Definitions from OpenAPI Spec:
"definitions": {
"BaseUserReq": {
"type": "object",
"discriminator": "type",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"name": {
"type": "string"
}
},
"title": "BaseUserReq"
},
"BaseUserRes": {
"type": "object",
"discriminator": "type",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"name": {
"type": "string"
}
},
"title": "BaseUserRes"
},
"EmployeeUserReq": {
"title": "EmployeeUser",
"allOf": [{
"$ref": "#/definitions/BaseUserReq"
}, {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"name": {
"type": "string"
}
},
"title": "EmployeeUserReq"
}]
},
"EmployeeUserRes": {
"title": "EmployeeUser",
"allOf": [{
"$ref": "#/definitions/BaseUserRes"
}, {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"name": {
"type": "string"
}
},
"title": "EmployeeUserRes"
}]
}
}