I use multiple DTOs for a same Entity.
For example, my entity:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity(name = "users")
public class User {
@Id //(with uuid generator)
private UUID id;
private String firstName;
private String lastName;
private String password;
private String phoneNumber;
private Attachment photo;
}
The problem is that request and response are not the same. For example, to register, a user must enter a firstName, lastName, password, and phoneNumber. but not the id and photo (file). I wrote another API that works with attachments
I return the user as follows:
{
"id": "c37f5b13-0698-41c8-a439-212484935567",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "123456789",
"photoUrl": "/api/attachment/3ac27460-1c60-11ec-9621-0242ac130002"
}
and my DTOs:
public class UserDto {
@Data
public static class SignUpParams {
private String firstName;
private String lastName;
private String password;
private String phoneNumber;
}
@Data
public static class SignInParams {
private String password;
private String phoneNumber;
}
@Data
public static class ResponseParams {
private UUID id;
private String firstName;
private String lastName;
private String phoneNumber;
private String photoUrl;
}
@Data
public static class BlaParams {
// Just the fields I want
}
}
I think this method does not return unnecessary null values and is not displayed in Swagger Api Docs.
Is it right and best practices to use a nested class for dtos? or is there another better option?
Overall if you follow OOP paradigm, inheritance is usually a bad choice. However because we're talking about DTOs which can barely be considered classes in the first (instead they are usually structures w/o logic), I'd relax the requirements. After all, we rarely write code that follows only one paradigm.
With that said, it's possible to replace the inheritance with a composition by using Jackson's
@JsonUnwrapped:@JsonUnwrappedwill embed fields of the enclosed object into the outer JSON.PS: You should almost never use
@Data- it implementshashCode()&equals()and it uses all fields for that. Do you compare your DTOs in production code? If not, why do you needequals()implemented in the first place? Most devs use this annotation simply because they are lazy and are fine with mediocre code.