2.3.1 Create Todo 구현

jaehyeok1230·2022년 11월 26일
0

퍼시스턴스 -> 서비스 -> 컨트롤러 순으로 구현한다.

로그 어노테이션

용도에 따라 크게 info, debug, warn, error으로 나누고 이를 로그 레벨이라고 부른다.

퍼시스턴스 구현

@Repository
public interface TodoRepository extends JpaRepository<TodoEntity, String> {
    List<TodoEntity> findByUserId(String userId);
}

엔티티 저장을 위해 JpaRepository가 제공하는 save메소드를 사용하고, 새 Todo 리스트를 반환하기 위해 findByUserId()메서드를 사용한다.

서비스 구현

메서드는 크게 세 단계로 구성되어 있다.

  • 검증 : 넘어온 엔티티가 유효한지 검사하는 로직. 이 부분은 코드가 더 커지면 TodoValidator.java로 분리시킬 수 있다.
  • Save() : 엔티티를 데이터베이스에 저장한다. 로그를 남긴다.
  • 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);
        }
    }
}

테스팅

0개의 댓글