TIL - 20250716

juni·2025년 7월 16일

TIL

목록 보기
66/317

0716 학습 정리: Spring Boot 회원 API with DTO, 유효성 검증, 로깅

✅ 1. 회원 생성 API 흐름 (REST)

MemberController5_3

  • URL: /api/v5-3/members
  • 기능: 회원 생성 (POST), 전체 회원 조회 (GET)
  • 데이터 저장: 메모리 Map (account를 key로 저장)

POST 요청 - 회원 생성

@PostMapping
public ResponseEntity<?> create(@RequestBody @Valid MemberCreateDto dto, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        Map<String, String> errorMap = new HashMap<>();
        bindingResult.getFieldErrors().forEach(err -> {
            errorMap.put(err.getField(), err.getDefaultMessage());
        });
        log.warn("회원가입 입력값 오류 발생!");
        return ResponseEntity.badRequest().body(errorMap);
    }

    Member member = MemberCreateDto.from(dto);
    memberStore.put(dto.getUserAcc(), member);
    return ResponseEntity.ok("created member: " + member);
}

GET 요청 - 회원 전체 조회

@GetMapping
public ResponseEntity<?> memberList() {
    log.trace("memberList 메서드 호출됨");
    log.info("회원 목록 요청 시작!");

    List<MemberListResponse> responses = memberStore.values().stream()
        .map(MemberListResponse::from)
        .collect(Collectors.toList());

    if (responses.isEmpty()) {
        log.warn("회원 데이터 없음");
        return ResponseEntity.notFound().build();
    }

    return ResponseEntity.ok(responses);
}

✅ 2. DTO 구조 및 검증

MemberCreateDto

  • 역할: 회원 가입 시 필요한 데이터 받는 전용 객체

  • 검증 어노테이션 사용:

    • @Email, @NotBlank, @Pattern
  • 정적 팩토리 메서드로 Entity 변환

@Email(message = "계정명은 이메일 형식 필요")
@NotBlank(message = "계정명은 필수")
private String userAcc;

@Pattern(regexp = ..., message = "비밀번호는 특수문자, 숫자 포함 8자 이상")
private String pw;

@NotBlank(message = "닉네임은 필수")
private String nick;

public static Member from(MemberCreateDto dto) {
    return Member.builder()
        .account(dto.getUserAcc())
        .password(dto.getPw())
        .nickname(dto.getNick())
        .build();
}

✅ 3. Entity와 응답 DTO 구성

Member (Entity)

  • 필드: uid, account, password, nickname
  • UUID 자동 생성으로 회원 식별
  • 빌더 패턴 사용하여 생성

MemberListResponse (응답 전용 DTO)

  • 필드: id, email, nick, creationTime
  • 닉네임은 마스킹 처리 (ex. 호돌이 → 호*이)
public static MemberListResponse from(Member member) {
    return MemberListResponse.builder()
        .id(member.getUid())
        .email(member.getAccount())
        .nick(maskingNickName(member.getNickname()))
        .creationTime(LocalDate.now())
        .build();
}

✅ 4. 로깅 전략

레벨용도 설명
TRACE흐름 추적용 (메서드 진입/종료 등)
DEBUG변수값 추적, 디버깅용 로그
INFO운영 중 발생하는 일반 상태 정보 기록
WARN심각하지 않지만 의심가는 상태
ERROR치명적인 예외 상황 기록

✅ 요약

  • DTO를 통한 요청 처리와 Entity 변환 로직 분리로 유지보수 용이
  • @Valid + BindingResult를 활용한 입력값 검증 구현
  • 빌더 패턴, 정적 팩토리 메서드로 객체 생성 일관성 확보
  • 로그 레벨을 구분하여 상황별 상태 추적 및 디버깅 가능

0개의 댓글