Controller에서도 Service 부분에서 설명한 것과 같이 BoardService를 생성자 주입으로 @RequiredArgsConstructor 어노테이션을 사용해서 주입시켜 준다.
REST API 원칙을 따라서 다음과 같이 API를 구성할거다.
HTTP Method | URI | 기능 |
---|---|---|
GET | /api/board/{id} | ID가 {id}인 Board를 반환 (R) |
POST | /api/board | Request Body로 온 BoardRequestDto를 DB에 저장 (C) |
PUT | /api/board/{id} | Request Body로 온 BoardRequestDto로 ID가 {id}인 엔티티 수정 (U) |
DELETE | /api/board/{id} | ID가 {id}인 엔티티 삭제 (D) |
GET | /api/boards | 전체 게시판 목록 반환 (R) |
일단 REST API이니 @RestController를 사용해 준다.
@RestController는 @Controller와 @ResponseBody를 합친 어노테이션이다.
그리고 모든 PATH 앞에 /api
가 붙도록 설계할 것이니 @RequestMapping("api")
로 설정해 준다.
로그를 출력하기 위해서 @Slf4j
도 추가해 주고, 프론트엔드에서 개발할 때 CORS 관련 오류가 뜨지 않도록 하기 위해서 @CrossOrigin(origins="*")
도 붙여준다.
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.jwkwon0817.codemosboard.domain.dto.board.BoardDto;
import me.jwkwon0817.codemosboard.domain.dto.board.BoardRequestDto;
import me.jwkwon0817.codemosboard.domain.services.BoardService;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
@CrossOrigin(origins = "*")
@Slf4j
public class BoardController {
private final BoardService boardService;
@GetMapping("/board/{id}")
public ResponseEntity<?> getBoard(@PathVariable Long id) {
BoardDto retrieve = boardService.retrieve(id).toDto();
log.info("Retrieved DTO: {}", retrieve);
return ResponseEntity.ok(retrieve);
}
@PostMapping("/board")
public ResponseEntity<?> createBoard(@RequestBody @Valid BoardRequestDto boardDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
log.error("Binding Result: {}", bindingResult.getAllErrors());
return ResponseEntity.badRequest().body(bindingResult.getAllErrors());
}
BoardDto createdBoard = boardService.createBoard(boardDto);
log.info("Created DTO: {}", createdBoard);
return ResponseEntity.ok(createdBoard);
}
@PutMapping("/board/{id}")
public ResponseEntity<?> updateBoard(@PathVariable Long id, @RequestBody @Valid BoardRequestDto boardDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
log.error("Binding Result: {}", bindingResult.getAllErrors());
return ResponseEntity.badRequest().body(bindingResult.getAllErrors());
}
BoardDto updatedBoard = boardService.updateBoarder(id, boardDto);
log.info("Updated DTO: {}", updatedBoard);
return ResponseEntity.ok(updatedBoard);
}
@DeleteMapping("/board/{id}")
public ResponseEntity<?> deleteBoard(@PathVariable Long id) {
boardService.deleteBoard(id);
log.info("Deleted id: {}", id);
return ResponseEntity.ok("Successfully deleted id: " + id);
}
@GetMapping("/boards")
public ResponseEntity<?> getBoards() {
log.info("Retrieved all boards");
return ResponseEntity.ok(boardService.retrieveAll());
}
}
인자로 받는 BoardRequestDto에 @Valid
라는 어노테이션이 붙여져 있는데 이 어노테이션은 DTO 편에서 @NotBlank로 설정한 조건에 충족하는지 검증하는 어노테이션이다.
조건에 충족하지 않는다면 DTO 편에서 설명한 것과 같이 BindingResult
에 오류가 전달된다.