Back-end/멋쟁이사자처럼

[멋쟁이 사자처럼] level7~9 구현

잔디🌿 2024. 4. 30. 21:43

 

오랜만에 클론코딩 과제가 나왔다...

 

level7 은 모두 구현이 되어있었다!

 

level8

 

GoalService

 public Long save(String name, String color, Long memberId) {
        // TODO [8단계] memberId로 회원을 조회하고, 조회에 실패하면 "회원 정보가 없습니다." 예외를 발생시키세요.
        Member member = memberRepository.findById(memberId)
                .orElseThrow(() ->new NoFoundException("회원정보가 없습니다."));
        // TODO [8단계] 조회된 회원 정보를 사용하여 새 Goal 객체를 생성하세요.
        Goal newGoal = new Goal(name,color,member);
        // TODO [8단계] 생성된 Goal 객체를 goalRepository에 저장하고, 저장된 Goal의 ID를 반환하세요.
        goalRepository.save(newGoal);
        return newGoal.getId();
    }

member 객체에서 findById로 회원을 조회하고 없으면 회원정보가 없습니다 라는 에러를 발생시킨다.

조회를 완료한다면 goal객체를 만들어서 goalRepsitory를 통해서 저장한다. 그 다음 생성된 객체의 id 값을 리턴한다.

 

public void update(Long goalId, String name, String color, Long memberId) {
        // TODO [8단계] memberId로 회원을 조회하고, 조회에 실패하면 "회원 정보가 없습니다." 예외를 발생시키세요.
        Member member = memberRepository.findById(memberId)
                .orElseThrow(() ->new NotFoundException("회원 정보가 없습니다."));
        // TODO [8단계] goalId로 목표(Goal)를 조회하고, 조회에 실패하면 "목표 정보가 없습니다." 예외를 발생시키세요.
        Goal goal = goalRepository.findById(goalId)
                .orElseThrow(() ->new NotFoundException("목표 정보가 없습니다."));
        // TODO [8단계] 조회된 Goal의 회원 정보가 입력된 memberId와 일치하는지 검증하세요.
        if(member.getId() != goal.getMember().getId()){
            throw new ForbiddenException("해당 목표에 대한 권한이 없습니다.");
        }
        // TODO [8단계] Goal 객체의 정보를 새로운 name과 color로 업데이트하세요.
        goal.update(name,color);
    }

회원정보가 없을때와 목표점수가 없을 때에는 위와 같은 방법으로 구현하였다. 그 다음 member의 id와 goal의 member의 id가 같은지 확인해보고 만약 아니라면 forbiddenException을 발생시킨다. 값을 갱신할 때에는 위와 다르게 goal객체 자체를 수정해야하므로 goal안에 있는 update를 사용하였다.

 

public void delete(Long goalId, Long memberId) {
        // TODO [8단계] memberId로 회원을 조회하고, 조회에 실패하면 "회원 정보가 없습니다." 예외를 발생시키세요.
        Member member = memberRepository.findById(memberId)
                .orElseThrow(() -> new NotFoundException("회원 정보가 없습니다."));
        // TODO [8단계] goalId로 목표(Goal)를 조회하고, 조회에 실패하면 "목표 정보가 없습니다." 예외를 발생시키세요.
        Goal goal = goalRepository.findById(goalId)
                .orElseThrow(() -> new NotFoundException("목표 정보가 없습니다."));
        // TODO [8단계] 조회된 Goal의 회원 정보가 입력된 memberId와 일치하는지 검증하세요.
        if (member.getId() != goal.getMember().getId()) {
            throw new ForbiddenException("해당 목표에 대한 권한이 없습니다.");
            // TODO [8단계] 검증이 완료되면 Goal을 goalRepository에서 삭제하세요.
        }
        goalRepository.delete(goal);
    }

delete기능은 나머지는 모두 위와 같이 구현하였고, goalRepsitory에 있는 delete기능을 사용하여 삭제하도록 하였다.

 

 public List<GoalResponse> findAllByMemberId(Long memberId) {
        // TODO [8단계] memberId로 모든 목표(Goal)를 조회하세요.
        List<Goal> goals = goalRepository.findAllByMemberId(memberId);
        // TODO [8단계] 조회된 Goal들을 GoalResponse 리스트로 변환하여 반환하세요.
        List<GoalResponse> responses = goals.stream()
                .map(goal -> new GoalResponse(goal.getId(), goal.getName(), goal.getColor()))
                .collect(Collectors.toList());

        return responses;
    }

모든 memberid에 해당하는 goal을 조회하고 이들을 goalResponse리스트로 반환하는 함수이다.

goal조회는 이미 goalRepsitory에 구현되어있는 기능으로 받았고, 이를 stream을 활용하여 새로운 리스트로 만들었다.

다 만든 배열은 반환한다.

 

 

GoalController

 

@PostMapping
    public ResponseEntity<Void> create(
            @Auth Long memberId,
            @RequestBody GoalCreateRequest request
    ) {
        // TODO [8단계] GoalCreateRequest에서 이름과 색상을 추출하여 goalService의 save 메소드를 호출하고, 생성된 Goal의 ID로 URI를 생성하여 ResponseEntity를 반환하세요.

        Long goalId = goalService.save(request.name(), request.color(), memberId);
        return ResponseEntity.created(URI.create("/goals/" + goalId)).build();

    }
    }

create에서는받은 GoalCreteRequest의 이름과 색상을 추출하여 save하는 것이다. 

request객체에서 getter을 사용하여 이름과 색상 정보를 얻어내고, 이를 goalService.save를 사용하여 저장한다. 그 다음 uri를 servletUriComponentsBuilder을 사용하여 얻어내고, 이를 리턴한다.

 

 @PutMapping("/{id}")
    public ResponseEntity<Void> update(
            @PathVariable("id") Long id,
            @Auth Long memberId,
            @RequestBody GoalUpdateRequest request
    ) {
        // TODO [8단계] GoalUpdateRequest에서 이름과 색상을 추출하고, id와 memberId를 함께 goalService의 update 메소드에 전달하여 Goal 정보를 업데이트한 후, ResponseEntity.ok()를 반환하세요.
        String name = request.getName();
        String color = request.getColor();

        goalService.update(id,name, color, memberId);
        return ResponseEntity.ok().build();
    }

request를 통해서 name 과 color 값을 가져오고 이를 goalService를 통해서 업데이트한다. 그다음 ResponseEntity.ok().build()를 리턴한다. 이는 성공적으로 완료되었지만, 사용자에게 따로 전달할 것이 없을 때 사용한다.(http 200 ok 반환)

 

 @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(
            @PathVariable("id") Long id,
            @Auth Long memberId
    ) {
        // TODO [8단계] id와 memberId를 goalService의 delete 메소드에 전달하여 Goal을 삭제하고, ResponseEntity.ok()를 반환하세요.
        goalService.delete(id,memberId);
        return ResponseEntity.ok().build();
    }

 

goalService로 delete한 다음 잘 맞으면 ResponseEntity.ok().build()를 리턴한다. 

 

@GetMapping("/my")
    public ResponseEntity<List<GoalResponse>> findMine(
            @Auth Long memberId
    ) {
        // TODO [8단계] memberId를 goalService의 findAllByMemberId 메소드에 전달하여 해당 회원의 모든 Goal 정보를 조회하고, 조회된 정보를 ResponseEntity.ok()에 담아 반환하세요.
        List<GoalResponse> goals = goalService.findAllByMemberId(memberId);
        return ResponseEntity.ok(goals);
    }

goalService.findAllByMember로 리스트를 받은 후 이를 ResponseEntity.ok().build()에 넣어 반환하면서 http 200 ok를 리턴한다.

 

level9

 

TodoController

    @PostMapping
    public ResponseEntity<Void> create(
            @Auth Long memberId,
            @RequestBody TodoCreateRequest request
    ) {
        // TODO [9단계] TodoCreateRequest에서 goalId, content, date를 추출하여 todoService의 save 메소드를 호출하고, 생성된 Todo의 ID로 URI를 생성하여 ResponseEntity를 반환하세요.
        Long id = todoService.save(request.goalId(),memberId,request.content(),request.date());
        return ResponseEntity.created(URI.create("/todos/" + id)).build();
    }

todoService에 구현되어있는 save를 통해 값들을 저장한다.

그 다음 uri를 만들어서 리턴한다.

 

@PostMapping("/{id}/check")
    public void check(
            @Auth Long memberId,
            @PathVariable("id") Long todoId
    ) {
        // TODO [9단계] todoId와 memberId를 todoService의 check 메소드에 전달하여 Todo를 완료 상태로 변경하세요.
        todoService.check(todoId,memberId);
    }

check를 호출하여 체크한다.

 

@PostMapping("/{id}/uncheck")
    public void uncheck(
            @Auth Long memberId,
            @PathVariable("id") Long todoId
    ) {
        // TODO [9단계] todoId와 memberId를 todoService의 uncheck 메소드에 전달하여 Todo를 미완료 상태로 변경하세요.
        todoService.uncheck(todoId,memberId);
    }

uncheck를 호출하여 체크를 해제한다.

 

  @PutMapping("/{id}")
    public void update(
            @Auth Long memberId,
            @PathVariable("id") Long todoId,
            @RequestBody TodoUpdateRequest request
    ) {
        // TODO [9단계] TodoUpdateRequest에서 content, date를 추출하고, todoId와 memberId를 함께 todoService의 update 메소드에 전달하여 Todo 정보를 업데이트하세요.
        todoService.update(todoId,memberId, request.content(), request.date());
    }

update를 호출하여 값을 갱신한다.

 

   @DeleteMapping("/{id}")
    public void delete(
            @Auth Long memberId,
            @PathVariable("id") Long todoId
    ) {
        // TODO [9단계] todoId와 memberId를 todoService의 delete 메소드에 전달하여 Todo를 삭제하세요.
        todoService.delete(memberId, todoId);
    }

delete를 호출하여 값을 삭제한다.

 

@GetMapping("/my")
    public ResponseEntity<List<TodoWithDayResponse>> findMine(
            @Auth Long memberId,
            @RequestParam(value = "year", required = true) int year,
            @RequestParam(value = "month", required = true) int month
    ) {
        // TODO [9단계] memberId와 YearMonth.of(year, month)를 todoService의 findAllByMemberIdAndDate 메소드에 전달하여 해당 기간의 모든 Todo를 조회하고, 조회된 정보를 ResponseEntity.ok()에 담아 반환하세요.
        List<TodoWithDayResponse> todos = todoService.findAllByMemberIdAndDate(memberId,YearMonth.of(year, month));
        return ResponseEntity.ok(todos);
    }

findAllByMemberIdAndDate를 호출하여 받은 리스트를 리턴한다.

 

 

level9는 level8과 거의 비슷했다!