일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- router
- 리액트오류
- 구글
- linkedhastset
- @Controller
- addallattributes()
- 데이터베이스
- JPA
- SEO
- 플러그인
- @Repository
- firebase
- @Query
- HttpSession
- useEffect
- @Entity
- 인텔리제이
- GA4
- GET
- post
- ChatGPT
- Polylang
- 구글알고리즘
- db
- mergeattributes()
- Thymeleaf
- 워드프레스
- Login
- set
- 구글애널리틱스
- Today
- Total
개발천재
[Spring Boot] @RestController, 효과적인 API 개발을 위한 핵심 가이드 본문
@RestController 이해하기
@RestController는 Spring에서 RESTful 웹 서비스를 쉽게 만들 수 있도록 도와주는 어노테이션이다.
내부적으로 @Controller와 @ResponseBody를 포함하고 있어, 별도로 @ResponseBody를 선언하지 않아도 자동으로 JSON 형식의 데이터를 반환한다. 주로 API를 개발할 때 사용되며, 클라이언트와 서버 간 데이터를 주고받는 엔드포인트를 만들 때 유용하다. 이를 활용하면 HTTP 요청을 처리하고, 적절한 응답을 ResponseEntity와 함께 쉽게 반환할 수 있어 RESTful API 개발을 보다 직관적이고 효율적으로 구현할 수 있다.
@RestController의 장점
@RestController의 큰 장점은 JSON 데이터를 자동으로 반환해주는 것이다.
기존의 @Controller에서는 데이터를 응답할 때 @ResponseBody를 붙여야 했지만, @RestController를 사용하면 별도의 설정 없이도 JSON 응답을 제공한다. 즉, API 서버를 만들 때 코드가 간결해지고, 프론트엔드(React, Vue 등)나 모바일 앱과 쉽게 데이터를 주고받을 수 있다.
✔ HTML을 반환하지 않고 JSON 데이터를 반환하는 API를 쉽게 만들 수 있음
✔ @ResponseBody를 따로 붙일 필요 없음
✔ RESTful API 서버 개발에 적합
@RestController과 @Controller의 차이점
@RestController는 HTML을 반환하지 않고 데이터를 반환하는 API를 만들 때 사용한다.
어노테이션 | 설명 | 반환값 |
@Controller | 일반적인 웹 페이지 반환 (HTML) | View (.html, .jsp) |
@RestController | REST API 응답을 위한 컨트롤러 | JSON or XML |
@Controller 사용 예제 (HTML 반환)
articleView.html을 반환하여 웹 페이지를 보여준다.
@Controller
@RequestMapping("/articles")
public class ArticleController {
@GetMapping("/{id}")
public String getArticle(Model model, @PathVariable Long id) {
model.addAttribute("article", new Article(id, "제목", "내용"));
return "articleView"; // `articleView.html`을 반환
}
}
@RestController 사용 예제 (JSON 반환)
웹 브라우저 또는 Postman, API 테스트 툴에서 JSON 데이터가 출력된다.
@RestController
@RequestMapping("/api/articles")
public class ArticleRestController {
@GetMapping("/{id}")
public Article getArticle(@PathVariable Long id) {
return new Article(id, "제목", "내용"); // JSON 형태로 응답
}
}
{
"id": 1,
"title": "제목",
"content": "내용"
}
.
@ResponseBody 없이 JSON을 반환하는 이유
@RestController는 내부적으로 모든 메서드에 @ResponseBody가 자동 적용된다. @ResponseBody는 메서드의 반환값을 뷰(HTML) 대신 JSON이나 XML 같은 데이터로 변환하는 역할을 한다.
@Controller를 사용하면 기본적으로 뷰(HTML 페이지)를 반환하는 구조이기 때문에, JSON이나 문자열 데이터를 응답하려면 @ResponseBody를 명시적으로 선언해야 한다. 하지만 @RestController는 @Controller와 @ResponseBody를 합친 개념이므로, 모든 메서드에 자동으로 @ResponseBody가 적용된다. 즉, 별도의 어노테이션 없이도 객체를 반환하면 Spring이 이를 JSON 형식으로 변환하여 응답한다. 덕분에 RESTful API 개발이 간결해지고, 프론트엔드나 모바일 클라이언트와 데이터를 주고받는 작업이 훨씬 편리해진다.
@Controller
@RequestMapping("/api/articles")
public class ArticleController {
@GetMapping("/{id}")
@ResponseBody // JSON으로 반환
public Article getArticle(@PathVariable Long id) {
return new Article(id, "제목", "내용");
}
}
@RestController와 JSON 데이터 전송 (@PostMapping)
@RequestBody를 사용하면, 클라이언트가 보낸 JSON 데이터를 Comment 객체로 변환해준다.
@RestController
@RequestMapping("/api/comments")
public class CommentRestController {
@PostMapping
public Comment createComment(@RequestBody Comment comment) {
System.out.println(comment);
return comment; // 저장된 데이터 반환
}
}
Postman이나 프론트엔드에서 아래 JSON을 전송하면 된다.
{
"id": 1,
"nickname": "홍길동",
"body": "안녕하세요!"
}
@RestController예시
@RestController
public class CommentApiController {
private final CommentService commentService;
private final ArticleService articleService;
public CommentApiController(CommentService commentService, ArticleService articleService) {
this.commentService = commentService;
this.articleService = articleService;
}
// 0. 예외 테스트
@GetMapping("api/exception")
public String exceptionHandler(){
throw new BadRequestException("예외 처리 테스트");
}
// 1. 댓글 조회
@GetMapping("/api/comments/{commentId}")
public ResponseEntity<?> commentSearch(
@PathVariable("commentId") Long commentId
) {
CommentDTO findComment = getDto(commentId, "댓글 조회에 실패했습니다");
return ResponseEntity.status(HttpStatus.OK).body(findComment);
}
// 2. 댓글 생성
@PostMapping("/api/articles/{articleId}/comments")
public ResponseEntity<?> commentCreate(
@PathVariable("articleId") Long articleId,
@RequestBody CommentDTO dto
) {
// 던져진 articleId가 존재하는지 확인
ArticleDTO existsArticle = articleService.getOneArticle(articleId);
// 없는 게시글이면 Exception 처리
if (ObjectUtils.isEmpty(existsArticle)) {
throw new BadRequestException("게시글 ID가 존재하지 않습니다.");
} else {
// 존재하면 댓글 추가하기
commentService.insertComment(articleId, dto);
return ResponseEntity.status(HttpStatus.OK)
.body(ApiResponseMessage.builder().message("댓글 생성 성공").build());
}
}
// 3. 댓글 수정
@PatchMapping("/api/comments/{commentId}")
public ResponseEntity<?> commentUpdate(
@PathVariable("commentId") Long commentId,
@RequestBody CommentDTO dto
) {
// URL의 commentId와 RequestBody의 commentId 가 동일한지 확인
if (!dto.getCommentId().equals(commentId)) {
throw new BadRequestException("댓글 수정 요청 오류");
}
// 수정 요청 commentId가 존재하는지 확인
CommentDTO result = getDto(commentId, "댓글 수정 실패");
// 존재하면 수정 요청
commentService.updateComment(dto);
return ResponseEntity.status(HttpStatus.OK)
.body(ApiResponseMessage.builder().message("댓글 수정 성공").build());
}
// 4. 댓글 삭제
@DeleteMapping("/api/comments/{commentId}")
public ResponseEntity<?> commentDelete(
@PathVariable("commentId") Long commentId
) {
// 삭제할 댓글 아이디 확인
CommentDTO result = getDto(commentId, "댓글삭제실패");
// 삭제 요청하기
commentService.deleteComment(result.getCommentId());
return ResponseEntity.status(HttpStatus.OK)
.body(ApiResponseMessage.builder().message("댓글 삭제 성공").build());
}
private CommentDTO getDto(Long commentId, String message) {
Map<String, Object> findComment = commentService.findByCommentId(commentId);
if (ObjectUtils.isEmpty(findComment.get("dto"))) {
throw new BadRequestException(message);
}
return (CommentDTO) findComment.get("dto");
}
}
'개발 준비 > Spring Boot' 카테고리의 다른 글
[Spring Boot] ResponseEntity, 유연한 HTTP 응답 처리하기 (2) | 2025.03.04 |
---|---|
[Spring Boot] JPA Cascade 완벽 가이드 (2) | 2025.02.27 |
[Spring Boot] JPQL로 이해하는 데이터베이스 접근 방식 (0) | 2025.02.27 |
[Spring Boot] JPA 매핑 어노테이션 정리 (1) | 2025.02.27 |
[Spring Boot] JPA 영속성 컨텍스트 완벽 이해: 개념부터 실전 활용까지 (1) | 2025.02.26 |