[멋쟁이 사자처럼] level7~9 구현
오랜만에 클론코딩 과제가 나왔다...
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과 거의 비슷했다!