Cześć
Jaka jest najlepsza praktyka co do typów obiektów, jakie REST endpointy powinny zwracać . Rozchodzi się tu głównie o to czy lepiej jest stosować DTO czy stricte model.
Cześć
Jaka jest najlepsza praktyka co do typów obiektów, jakie REST endpointy powinny zwracać . Rozchodzi się tu głównie o to czy lepiej jest stosować DTO czy stricte model.
Zwracasz dto, czyli struktury danych.
Myślę, że możesz sam to spróbować sobie przeanalizować.
Wyobraź sobie model np.:
public class Department {
private String name;
private LocalDate creationDate;
private List<Employee> employees;
private Employee head;
// getters, setters etc.
}
Wyobraź sobie teraz następujące wymagania:
Co będzie lepiej zwracać. Za każdym razem cały obiekt Department
, czy może jednak projekcje w postaci dedykowanych POJO/DTO?
Nie mówiąc, o zaśmiecaniu swojego modelu adnotacjami i metodami niezbędnymi do transformacji do postaci wyjściowej (np. application/json
).
Wówczas, taki model potrafi wyglądać tak (tak, widziałem podobne tworki w jednym z projektów, przy którym miałem przyjemność pracować):
@NamedQueries({
@NamedQuery(name = "Department.findByName", query = "select d from Department d where d.name = :name"),
@NamedQuery(name = "Department.findByHeadId", query = "select d from Department d left join fetch d.head h where h.id = :headId")
})
@NamedEntityGraph(
name = "DepartmentWithEmployeesByName",
attributeNodes = {
@NamedAttributeNode(value = "name"),
@NamedAttributeNode(value = "employees", subgraph = "employeesGraph")
},
subgraphs= {
@NamedSubgraph(
name = "employeesGraph",
attributeNodes = {
@NamedAttributeNode(value = "firstName"),
@NamedAttributeNode(value = "lastName"),
@NamedAttributeNode(value = "position")
}
)
}
)
@Entity
@Table(name = "department")
@JsonPropertyOrder({"name","head","creationDate","employees"})
@JsonRootName("department")
public class Department {
@Column(length = 100, name = "name")
private String name;
@Column(name = "creation_date")
@Temporal(TemporalType.DATE)
@Convert(converter = LocalDateJpaConverter.class)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate creationDate;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "headId")
private Employee head;
// some endpoints require creation date in number format
@JsonProperty("creationDateNumber")
public Long getCreationDateNumber() {
return creationDate.toEpochDay();
}
@JsonSetter("creationDateNumber")
public void setCreationDateNumber(Long epochDay) {
creationDate = LocalDate.ofEpochDay(epochDay);
}
// getters, setters etc.
}
DTO - w razie zmian na bazie danych i aktualizacji modelu bazy zmiany mogą rozpropagować się od razu aż do API. Na pewno tego chcesz?