قبل ما ننتقل لمرحلة الـ Database، لازم نتعلم مفهوم مهم جداً رح يساعدنا بالفيديوهات الجاية: Data Transfer Objects (DTOs).
الـ DTO هو Object بسيط وظيفته نقل البيانات بين طبقات مختلفة من النظام، مثل من قاعدة البيانات إلى المستخدم أو بين الـ Services.
الـ DTO:
بالدروس السابقة، الـ Controller كان يستقبل الـ Employee Entity كاملة من الـ Client:
@PostMapping
public ResponseEntity<...> create(@RequestBody Employee employee) { ... }
هذا بيعني أن الـ Client يقدر يبعث أي خاصية حاب، بما فيها:
id - لازم النظام هو يحدده، مش الـ ClientdepartmentId - نحن نتحكم فيه، مش الـ Clientبننشئ Package اسمها dto وفيها نستخدم Java Records:
public record EmployeeCreate(
@NotBlank(message = "First name is required")
String firstName,
@NotBlank(message = "Last name is required"
اشترك في النشرة البريدية
دروس جديدة، مقالات، وأدوات مباشرة لبريدك.
لاحظ:
id - لأنو النظام هو اللي بينشئهdepartmentId - لأنو نحن بنتحكم فيهللـ Update ممكن نقرر إنو الـ Client ما يقدر يغير الـ Email (مثل حسابات Google):
public record EmployeeUpdate(
@NotBlank(message = "First name is required")
String firstName,
@NotBlank(message = "Last name is required")
String lastName,
@NotBlank(message = "Phone number is required")
String phoneNumber,
@NotBlank(message = "Position is required")
String position
) {}الـ email وhireDate مش موجودين هون - الـ Client ما بيقدر يغيرهم.
بنعدل الـ Controller يستخدم الـ DTOs:
@PostMapping
public ResponseEntity<GlobalResponse<Employee>> create(
@Valid @RequestBody EmployeeCreate employeeCreate) {
var created = employeeService.create(employeeCreate);
return new ResponseEntity<>(new GlobalResponse<>(created), HttpStatus.CREATED);
}
@PutMapping("/{employeeId}")
public ResponseEntity<GlobalResponse<Employee>> update(
@PathVariable UUID employeeId,
@Valid @RequestBody EmployeeUpdate employeeUpdate) {
var updated = employeeService.updateOne(employeeId, employeeUpdate);
return new ResponseEntity<>(new GlobalResponse<>(updated), HttpStatus.OK);
}وبالـ Service، بنحول الـ DTO لـ Entity:
@Override
public Employee create(EmployeeCreate dto) {
Employee employee = new Employee();
employee.setId(UUID.randomUUID());
employee.setFirstName(dto.firstName());
employee.setLastName(dto.lastName());
employee.setEmail(dto.email());
employee.setPhoneNumber(dto.phoneNumber());
employee.setHireDate(dto.hireDate());
employee.setPosition(dto.position());
employee.setDepartmentId(null);
employees.add(employee);
return employee;
}لاحظ أن الـ Record بنوصل لـ Properties تاعته بدون get - يعني dto.firstName() مش dto.getFirstName().
الـ DTO مش بس للـ Input - ممكن تستخدمه للـ Output برضو. مثلاً لو الـ Employee عنده password، ما بدنا نرجعه للـ Client:
public record EmployeeResponse(
UUID id,
String firstName,
String lastName,
String email,
String position
) {}هيك بتتحكم بالضبط شو البيانات اللي تطلع للـ Client، وما ترجع حاجات حساسة مثل الباسورد.
بالدروس الجاية رح نتعامل مع الـ DTOs بشكل أكبر.