Spring/강의

[📕 기초 Spring] 5-4. 메모장 프로젝트 - ver2 (프론트 컨트롤러, 어댑터 패턴 적용)

가지코딩 2025. 5. 4. 23:04

메모장 프로젝트 ver1 의 문제점

  • 실제 문제의 원인을 파악하기 어렵거나 잘못된 정보 전달 및 처리가 될 수 있다.
    1. 응답 코드가 세분화 되어있지 않다.(성공 시 모두 200OK)
    2. 적절한 예외가 발생하지 않는다.(실패 시 모두 500 Error 발생)
  • 서버가 종료된 후 다시 켜지면 데이터가 모두 초기화 된다.

📕 목차

    1. 요구사항 분석 및 설계
    2. 메모 생성 기능
    3. 메모 목록 조회 기능
    4. 메모 단 건 조회 기능
    5. 메모 단 건, 전체 수정 기능
    6. 메모 단 건 제목 수정 기능
    7. 메모 삭제 기능
    8. 해결한 문제점 & 문제점

1. 요구사항 분석 및 설계

메모장 API 요구사항

  1. 통신 데이터 형태는 JSON이다.
  2. 각각의 메모는 식별자(id), 제목(title), 내용(contents)으로 구성되어 있다.
  3. 응답을 각각의 API에 알맞게 해야 한다.
  4. 메모를 생성할 수 있다. (CREATE)
    • 메모 생성 시 제목, 내용이 필요하다.
    • 생성된 데이터(식별자, 제목, 내용)가 응답된다.
  5. 메모 전체 목록을 조회할 수 있다. (READ)
    • 여러 개의 데이터를 배열 형태로 한번에 응답한다.
    • 데이터가 없는 경우 비어있는 배열 형태로 응답한다.
  6. 메모 하나를 조회할 수 있다. (READ)
    • 조회할 memo에 대한 식별자 id값이 필요하다.
    • 조회된 데이터가 응답된다.
    • 조회될 데이터가 없는 경우 Exception이 발생한다.
  7. 메모 하나를 전체 수정(덮어쓰기)할 수 있다. (UPDATE)
    • 수정할 memo에 대한 식별자 id값이 필요하다.
    • 수정할 요청 데이터(제목, 내용)가 꼭 필요하다.
    • 수정된 데이터가 응답된다.
    • 수정될 데이터가 없는 경우 Exception이 발생한다.
  8. 메모 하나의 제목을 수정(일부 수정)할 수 있다. (UPDATE)
    • 수정할 memo에 대한 식별자 id값이 필요하다.
    • 수정할 요청 데이터(제목)가 꼭 필요하다.
    • 수정된 데이터가 응답된다.
    • 수정될 데이터가 없는 경우 Exception이 발생한다.
  9. 메모를 삭제할 수 있다. (DELETE)
    • 삭제할 memo에 대한 식별자 id값이 필요하다.
    • 삭제될 데이터가 없는 경우 Exception이 발생한다.

2. 메모 생성 기능

메모를 생성 요구사항 (CREATE)

  • 메모 생성시 제목, 내용이 필요하다.
  • 생성된 데이터(식별자, 제목, 내용)가 응답된다.
    • 응답 상태코드는 201 CREATED로 설정한다.

[실습]

 

MemoController 클래스 ( /controller/MemoController.java )

  • 응답코드를 함께 반환하도록 수정.
  • ResponseEntity 반환
@PostMapping
public ResponseEntity<MemoResponseDto> createMemo(@RequestBody MemoRequestDto dto) {
    Long memoId = memoList.isEmpty() ? 1 : Collections.max(memoList.keySet()) + 1;

    Memo memo = new Memo(memoId, dto.getTitle(), dto.getContents());

    memoList.put(memoId, memo);

    // ResponseEntity 반환
    return new ResponseEntity<>(new MemoResponseDto(memo), HttpStatus.CREATED);
}

 

[실습 결과]


3. 메모 목록 조회 기능

메모 전체 목록을 조회 요구사항 (READ)

  • 여러개의 데이터를 배열 형태로 한번에 응답한다.
  • 데이터가 없는 경우 비어있는 배열 형태로 응답한다.
  • 응답 상태코드는 200 OK로 설정한다.

[실습]

 

MemoController 클래스 ( /controller/MemoController.java )

  • findAllMemos() 메서드 추가
@GetMapping
public ResponseEntity<List<MemoResponseDto>> findAllMemos() {
    List<MemoResponseDto> responseList = new ArrayList<>();

    for (Memo memo : memoList.values()) {
        MemoResponseDto responseDto = new MemoResponseDto(memo);
        responseList.add(responseDto);
    }

    return new ResponseEntity<>(responseList, HttpStatus.OK);
}

 

 

[실습 결과]


4. 메모 단 건 조회 기능

메모 단 건 조회 요구사항 (READ)

  • 조회할 memo에 대한 식별자 id값이 필요하다.
  • 조회된 데이터가 응답된다.
    • 응답 상태코드는 200 OK로 설정한다.
  • 조회될 데이터가 없는 경우 Exception이 발생한다.
    • 응답 상태코드는 404 NOT FOUND로 설정한다.

[실습]

 

MemoController 클래스 ( /controller/MemoController.java )

  • findMemoById() 메서드 수정
@GetMapping("/{id}")
public ResponseEntity<MemoResponseDto> findMemoById(@PathVariable Long id) {
    Memo memo = memoList.get(id);

    // NPE 방지
    if (memo == null) {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    return new ResponseEntity<>(new MemoResponseDto(memo), HttpStatus.OK);
}

 

 

[실습 결과]


5. 메모 전체 수정 기능

메모(단 건) 전체 수정 기능 (UPDATE)

  • 수정할 memo에 대한 식별자 id값이 필요하다.
  • 수정할 요청 데이터(제목, 내용)가 꼭 필요하다.
  • 수정된 데이터가 응답된다.
    • 응답 상태코드는 200 OK로 설정한다.
  • 수정될 데이터가 없는 경우 Exception이 발생한다.
    • 응답 상태코드는 404 NOT FOUND 로 설정한다.

[실습]

 

MemoController 클래스 ( /controller/MemoController.java )

  • updateMemoById() → updateMemo() 메서드 수정
@PutMapping("/{id}")
public ResponseEntity<MemoResponseDto> updateMemo(@PathVariable Long id, @RequestBody MemoRequestDto dto) {
    Memo memo = memoList.get(id);

    // NPE 방지
    if (memo == null) {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    // 필수값 검증
    if (dto.getTitle() == null || dto.getContents() == null) {
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }

    memo.update(dto);

    return new ResponseEntity<>(new MemoResponseDto(memo), HttpStatus.OK);
}

 

 

[실습 결과]


6. 메모 제목 수정 기능

메모(단 건) 일부 수정 기능 (UPDATE)

  • 수정할 memo에 대한 식별자 id값이 필요하다.
  • 수정할 요청 데이터(제목)이 꼭 필요하다.
    • 응답 상태코드는 400 BAD REQUEST로 설정한다.
  • 수정된 데이터가 응답된다.
    • 응답 상태코드는 200 OK로 설정한다.
  • 수정될 데이터가 없는 경우 Exception이 발생한다.
    • 응답 상태코드는 404 NOT FOUND 로 설정한다.

[실습]

 

MemoController 클래스 ( /controller/MemoController.java )

  • updateTitle() 메서드 수정
@PatchMapping("/{id}")
public ResponseEntity<MemoResponseDto> updateTitle(@PathVariable Long id, @RequestBody MemoRequestDto requestDto) {
    Memo memo = memoList.get(id);

    // NPE 방지
    if (memo == null) {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
    // 필수값 검증
    if (requestDto.getTitle() == null || requestDto.getContents() != null) {
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }

    memo.updateTitle(requestDto);

    return new ResponseEntity<>(new MemoResponseDto(memo), HttpStatus.OK);
}

 

 

[실습 결과]

 


7. 메모 삭제 기능

메모 삭제 기능 (DELETE)

  • 삭제할 memo에 대한 식별자 id값이 필요하다.
  • 삭제될 데이터가 없는 경우 Exception이 발생한다.
    • 응답 상태코드는 404 NOT FOUND로 설정한다.
  • 응답 데이터는 없어도 무방하다.
    • 응답 상태코드는 200 OK로 설정한다.

[실습]

 

MemoController 클래스 ( /controller/MemoController.java )

  • deleteMemo() 메서드 수정
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteMemo(@PathVariable Long id) {

    if (memoList.containsKey(id)) {
        memoList.remove(id);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

 

* void와 Void의 차이점

항목 void Void
타입 기본 타입 (primitive) 참조 타입 (reference)
용도 반환값 없음 제네릭 등의 리턴 타입으로 사용
객체화 불가 null만 가능
대표 사용 메서드 선언 Callable<Void>, Future<Void> 등

 

 

[실습 결과]


8. 해결한 문제점 & 문제점

해결한 문제점

  • 실제 문제의 원인을 파악하기 어렵거나 잘못된 정보 전달 및 처리가 될 수 있다.
    1. 응답 코드가 세분화 되어있지 않다.(성공 시 모두 200OK)
    2. 적절한 예외가 발생하지 않는다.(실패 시 모두 500 Error 발생)

문제점

  • Controller에 책임이 너무 많다.(요청, 비지니스 로직, 응답, 예외 처리 등)
  • 서버가 종료된 후 다시 켜지면 데이터가 모두 초기화 된다.

실습 코드

https://github.com/gajicoding/spring-crud-memo/tree/v1.2.0

 

GitHub - gajicoding/spring-crud-memo

Contribute to gajicoding/spring-crud-memo development by creating an account on GitHub.

github.com