퍼시스턴스 -> 서비스 -> 컨트롤러 순으로 구현한다.
용도에 따라 크게 info, debug, warn, error으로 나누고 이를 로그 레벨이라고 부른다.
@Repository
public interface TodoRepository extends JpaRepository<TodoEntity, String> {
List<TodoEntity> findByUserId(String userId);
}
엔티티 저장을 위해 JpaRepository가 제공하는 save메소드를 사용하고, 새 Todo 리스트를 반환하기 위해 findByUserId()메서드를 사용한다.
메서드는 크게 세 단계로 구성되어 있다.
public List<TodoEntity> create(final TodoEntity entity) {
//Validations
if (entity == null) {
log.warn("Entity cannot be null");
throw new RuntimeException("Entity cannot be null.");
}
if (entity.getUserId() == null) {
log.warn("Unknown user");
throw new RuntimeException("Unknown user.");
}
repository.save(entity);
log.info("Entity Id : {} is saved.", entity.getId());
return repository.findByUserId(entity.getUserId());
}
public List<TodoEntity> create(final TodoEntity entity) {
//Validations
vaildate(entity);
repository.save(entity);
log.info("Entity Id : {} is saved.", entity.getId());
return repository.findByUserId(entity.getUserId());
}
//리팩토링한 메서드
private void vaildate(final TodoEntity entity) {
if (entity == null) {
log.warn("Entity cannot be null");
throw new RuntimeException("Entity cannot be null.");
}
if (entity.getUserId() == null) {
log.warn("Unknown user");
throw new RuntimeException("Unknown user.");
}
}
TodoDTO.java에 DTO를 Entity로 변환하기 위해 toEntity메서드 작성
@NoArgsConstructor
@AllArgsConstructor
@Data
public class TodoDTO {
private String id;
private String title;
private boolean done;
public TodoDTO(final TodoEntity entity) {
this.id = entity.getId();
this.title = entity.getTitle();
this.done = entity.isDone();
}
public static TodoEntity toEntity(final TodoDTO dto) {
return TodoEntity.builder()
.id(dto.getId())
.title(dto.getTitle())
.done(dto.isDone())
.build();
}
}
컨트롤러 구현
@RestController
@RequestMapping("todo")
public class TodoController {
@Autowired
private TodoService service;
//testTodo 생략
@PostMapping
public ResponseEntity<?> createTodo(@RequestBody TodoDTO dto) {
try {
String temporaryUserId = "temporary-user"; // temporary user id.
// (1) TodoEntity로 변환한다.
TodoEntity entity = TodoDTO.toEntity(dto);
// (2) id를 null로 초기화한다. 생성 당시에는 id가 없어야 하기 때문이다.
entity.setId(null);
// (3) 임시 유저 아이디를 설정해준다. 4장에서 고칠예정
entity.setUserId(temporaryUserId);
// (4) 서비스를 이용해 Todo 엔티티를 생성한다.
List<TodoEntity> entities = service.create(entity);
// (5) 자바 스트림을 이용해 리턴된 엔티티 리스트를 TodoDTO 리스트로 변환한다.
List<TodoDTO> dtos = entities.stream().map(TodoDTO::new).collect(Collectors.toList());
// (6) 변환된 TodoDTO 리스트를 이용해 ResponseDTO를 초기화한다.
ResponseDTO<TodoDTO> response = ResponseDTO.<TodoDTO>builder().data(dtos).build();
// (7) ResponseDTO를 리턴한다.
return ResponseEntity.ok().body(response);
} catch (Exception e) {
// (8) 혹시 예외가 나는 경우 dto 대신 error에 메시지를 넣어 리턴한다.
String error = e.getMessage();
ResponseDTO<TodoDTO> response = ResponseDTO.<TodoDTO>builder().error(error).build();
return ResponseEntity.badRequest().body(response);
}
}
}