Sobes.tech
Senior

Description of the task: It is required to implement a REST endpoint to retrieve a list of insurance policies that belong to a specified client and are paid. Since there are a very large number of policies in the system, a parameter for limiting the result should be provided. @RestController public class ClientController { @Value("policy.limit") private int policyLimit; @Autowired private PolicyService policyService; @RequestMapping(path = "client/{clientId}/policies", method = RequestMethod.POST) public Response getClientPolicies(@PathVariable("clientId") String clientId) { List<PolicyDTO> policies = getPolicies().stream() .limit(policyLimit) .filter(p -> p.getClientIds().contains(clientId)) .filter(p -> p.isPaid()) .toList(); return new Response(policies); } @Transactional private List<PolicyDTO> getPolicies() { return policyService.getPolicies(); } @Data @AllArgsConstructor public class Response { private List<PolicyDTO> policies; } @Data public class PolicyDTO { private String id; private String name; private List<String> clientId; private Boolean isPaid; } @RequiredArgsConstructor @Component public class PolicyService { private PolicyDbRepository repository; List<PolicyDTO> getPolicies() { return repository.getPolicies(); } } public interface PolicyDbRepository { List<PolicyDTO> getPolicies(); }

sobes.tech AI

Answer from AI

The provided code has several issues:

  1. The getPolicies() method loads all policies from the database, and then filtering and limiting the results occur in memory. This is inefficient with large data volumes.
  2. The policyLimit parameter is applied before filtering, which may lead to returning an incomplete or incorrect dataset.
  3. Using the HTTP POST method is not suitable for data retrieval; GET should be used instead.

The correct approach is to implement filtering and limiting at the database query level to fetch only the necessary policies.

Example of a corrected controller:

@RestController
@RequestMapping("/client")
public class ClientController {

    @Autowired
    private PolicyService policyService;

    @GetMapping("/{clientId}/policies")
    public ResponseEntity<List<PolicyDTO>> getClientPolicies(
            @PathVariable String clientId,
            @RequestParam(defaultValue = "10") int limit) {
        List<PolicyDTO> policies = policyService.getPaidPoliciesByClient(clientId, limit);
        return ResponseEntity.ok(policies);
    }
}

@Service
public class PolicyService {

    @Autowired
    private PolicyDbRepository repository;

    public List<PolicyDTO> getPaidPoliciesByClient(String clientId, int limit) {
        return repository.findPaidPoliciesByClient(clientId, limit);
    }
}

public interface PolicyDbRepository {
    List<PolicyDTO> findPaidPoliciesByClient(String clientId, int limit);
}

In this example, filtering and limiting are done in the repository, which allows efficient handling of large data volumes.