Cuando implementamos nuestros servicios REST que devuelven objetos de la lógica de negocio de nuestra aplicación se pueden dar dos casos: los objetos que devolvemos son entidades, nuestros objetos no son entidades.
Si los objetos son entidades, estaremos exponiendo todos sus datos y en muchos casos no querremos enviarlo todo. Por ejemplo si guardase en una entidad los valores usuario y password, no debemos enviar dicho password como respuesta del JSON. Ante esta situación podríamos usar la anotación @JsonIgnore que fuerza que ese campo no se envíe, pero se aplicaría a todos los casos.
Si a partir de una entidad según en caso quisiéramos mandar un conjunto de campos diferente, la anotación @JsonIngore no es suficiente. En general las buenas prácticas de uso de servicios REST nos indican que siempre devolvamos objetos DTO y no expongamos las entidades de negocio, por tanto debemos seguir esta directríz.
Para evitar que la generación de la respuesta como DTO añada complejidad a nuestro código, es recomendable usar elementos de la programación funcional disponibles desde Java8. El modo de proceder debería ser similar al siguiente:
Método tradicional:
@GetMapping("api/{version}/usuarios")
public List<Usuario> listarUsuarios() {
return this.usuarioService.findAll(); //Llamamos al servicio de usuarios que devolverá una lista de todos los usuarios del sistema (son Entidades).
} |
Devolviendo DTO con programación funcional:
@GetMapping("api/{version}/usuarios")
public List<UsuarioDTO> listarUsuarios() {
return this.usuarioService.findAll().parallelStream().map(Usuario::toDTO).collect(Collectors.toList());
} |
La llamada usando programación funcional hace lo siguiente: