Skip to content
Advertisement

Showing a specific JSON response for my GET endpoint

I have a many-to-many relationship between Department and Employee Image of the Employee Service Schema

I have already done a mapping for the GET endpoint which returns a list of departments that contain Employees, this is the request: http://localhost:8080/api/departments/1/employees, and this is the response I get:

[
    {
    "id": {
    "deptNo": "1 ",
    "empNo": 2
    },
    "fromDate": "2021-11-22",
    "toDate": null
    }
]

This is the code that gets the job done:

Department Repository Imp

@Override
public Optional<Department> findByIdWithEmployees(String deptNo) {
    TypedQuery<Department> query = this.entityManager.createQuery("SELECT d  FROM Department d JOIN FETCH d.employees e WHERE d.deptNo = :deptNo AND e.toDate IS NULL", Department.class).setParameter("deptNo", deptNo);
    return Optional.ofNullable(query.getSingleResult());
}

Employee Service Impl

@Override
public List<DepartmentEmployee> listAllEmployeesPerDepartment(String deptNo) {
    Department department = this.departmentRepository.findByIdWithEmployees(deptNo).orElseThrow(() -> new DepartmentNotFoundException(deptNo));
    return department.getEmployees();
}

Department Controller

@GetMapping("/{deptNo}/employees")
public List<DepartmentEmployee> getEmployeesPerDepartment(@PathVariable String deptNo) {
    return this.employeeService.listAllEmployeesPerDepartment(deptNo);
}

Now what I need is to re-map this so I get a different response. This is the response I need to receive when I run a GET request:

[
  {
    "fromDate":"2021-11-22",
    "toDate":null,
    "employee":{
      "empNo":2,
      "birthDate":"1997-05-10",
      "firstName":"Taulant",
      "lastName":"Fazliu",
      "gender":"M",
      "hireDate":"2020-01-01"
    }
  }
]

How to achieve this?

Advertisement

Answer

If the response you want to give has a different structure from your model (the first diagram you showed), you need to implement the DTO pattern.

DTO: Data Transfer Object. It just means, in words of Samuel L. Jackson “hey you! Do you want to show your shit in a different way? Create a new mother fucker object that represents the new shit, and damn transform it!

So, create a new object called DepartmentEmployeeDTO with the structure you want to show, and use a Builder pattern to transform from one to another. And of course make getEmployeesPerDepartment return List<DepartmentEmployeeDTO>. That method will end up as something like this:

@GetMapping("/{deptNo}/employees")
public List<DepartmentEmployeeDTO> getEmployeesPerDepartment(@PathVariable String deptNo) {
    return this.employeeService.listAllEmployeesPerDepartment(deptNo)
        .stream()
        .map(e -> new DepartmentEmployeeDTOBuilder(e).build())
        .collect(Collectors.toList());
}

That provided you build you Builder with one constructor with the original DepartmentEmployee as the only parameter.

9 People found this is helpful
Advertisement