@RestController vs @Controller
by 볼빵빵오춘기혼자 토이 프로젝트를 하다 @Controller만 이용하다가 '@RestController도 있잖아'라는 생각이 들었다.
그래서 @RestController와 @Controller를 비교해보기로 했다.
글 쓰기, 글 수정하기, 글 삭제하기, 글 읽기, 댓글, 전체 글 조회(리스트) 기능을 구현할 때 어떤 애노테이션을 사용하는 것이 좋을까?
@RestController와 @Controller는 Spring MVC에서 주로 사용되는 두 가지 애노테이션이다. 이 두 애노테이션은 서로 다른 용도로 사용되며, 각각의 특성과 사용 방법에 대해 자세히 알아보자.
@Controller
- @Controller는 전통적인 MVC 패턴에서 사용되는 애노테이션으로, 주로 HTML 페이지를 반환하는 데 사용된다.
- Spring MVC의 뷰 리졸버(View Resolver)와 함께 사용되어 JSP, Thymeleaf, FreeMarker 등과 같은 템플릿 엔진을 통해 HTML 페이지를 생성한다.
- 따라서 @Controller는 주로 사용자가 브라우저를 통해 접근하는 웹 애플리케이션을 개발할 때 사용된다.
ex) 사용자가 회원가입 폼을 작성하고 제출하는 웹 페이지를 반환할 때 사용된다.
@Controller
public class UserController {
@GetMapping("/register")
public String showRegistrationForm() {
return "register";
}
@PostMapping("/register")
public String registerUser(@RequestParam String username, @RequestParam String password, Model model) {
// 사용자 등록 로직 처리
model.addAttribute("username", username);
return "welcome";
}
}
⇒ /register URL에 접근하면 register.html 페이지를 반환. 사용자가 폼을 제출하면 welcome.html 페이지를 반환.
@RestController
- @RestController는 RESTful 웹 서비스(API)를 만들 때 사용되는 애노테이션이다.
- @Controller와 @ResponseBody를 합친 것으로, 반환되는 데이터는 뷰가 아닌 JSON이나 XML 형식의 데이터이다.
- 따라서, @RestController는 주로 클라이언트 애플리케이션(모바일 앱, 프론트엔드 JavaScript 애플리케이션 등)이 데이터를 요청할 때 사용된다.
ex) 클라이언트가 사용자 정보를 요청하면 JSON 형식의 데이터를 반환한다.
@RestController
public class UserRestController {
@GetMapping("/api/users/{id}")
public User getUser(@PathVariable Long id) {
// 사용자 정보 조회 로직
return new User(id, "username", "password");
}
@PostMapping("/api/users")
public User createUser(@RequestBody User user) {
// 사용자 생성 로직
return user;
}
}
⇒ /api/users/{id} URL에 GET 요청을 보내면 사용자 정보를 JSON 형식으로 반환. /api/users URL에 POST 요청을 보내면 새로운 사용자를 생성하고 그 정보를 JSON 형식으로 반환.
요약
@Controller
- 주로 웹 애플리케이션에서 HTML 페이지를 반환할 때 사용된다.
- 사용자가 브라우저를 통해 접근하고, 서버에서 HTML 페이지를 렌더링하여 반환할 때 적합하다.
@RestController
- RESTful API를 구현할 때 사용되며, 주로 JSON이나 XML 형식의 데이터를 반환한다.
- 프론트엔드 애플리케이션이나 모바일 앱이 데이터를 요청할 때 적합하다.
정리
글 쓰기, 글 수정하기, 글 삭제하기, 글 읽기, 댓글, 전체 글 조회(리스트) 어떤 걸 쓰는게 좋을까? 에 대한 생각을 정리해봤다.
글쓰기 (Create), 글 수정하기 (Update)
⇒ @Controller가 적절
- 사용자가 브라우저를 통해 글 작성 폼을 제출할 때 주로 사용된다.
- 폼 제출 후 성공/실패 메시지나 리디렉션을 처리하기 적합하기 때문이다.
@Controller
public class PostController {
// 글 쓸 때
@GetMapping("/posts/new")
public String showCreateForm(Model model) {
model.addAttribute("post", new Post());
return "create-post";
}
@PostMapping("/posts")
public String createPost(@ModelAttribute Post post) {
postService.save(post);
return "redirect:/posts";
}
// 글 수정할 때
@GetMapping("/posts/{id}/edit")
public String showEditForm(@PathVariable Long id, Model model) {
Post post = postService.findById(id);
model.addAttribute("post", post);
return "edit-post";
}
@PostMapping("/posts/{id}")
public String updatePost(@PathVariable Long id, @ModelAttribute Post post) {
postService.update(id, post);
return "redirect:/posts";
}
}
글 읽기(Read)
⇒ @Controller가 적절
- 사용자가 브라우저를 통해 글을 읽을 때 HTML 페이지로 제공한다.
@Controller
public class PostController {
@GetMapping("/posts/{id}")
public String readPost(@PathVariable Long id, Model model) {
Post post = postService.findById(id);
model.addAttribute("post", post);
return "view-post";
}
}
글 삭제하기 (Delete)
⇒ @RestController가 적절
- 글 삭제는 비동기적으로 수행되는 경우가 많고, 삭제 후 페이지 리디렉션이 필요 없을 때가 많다.
- 또한, RESTful API에서는 주로 JSON 응답을 사용한다.
@RestController
@RequestMapping("/api/posts")
public class PostRestController {
@DeleteMapping("/{id}")
public ResponseEntity<Void> deletePost(@PathVariable Long id) {
postService.delete(id);
return ResponseEntity.noContent().build();
}
}
전체 글 조회 (List)
⇒ @Controller와 @RestController 둘 다 사용 가능, 상황에 따라 다름.
- @Controller: 사용자가 브라우저를 통해 전체 글 목록을 HTML 페이지로 볼 때 적합하다.
- @RestController: JSON 형식으로 전체 글 목록을 제공할 때 적합하다. 프론트엔드 애플리케이션이나 모바일 앱에서 사용된다.
@Controller
public class PostController {
@GetMapping("/posts")
public String listPosts(Model model) {
List<Post> posts = postService.findAll();
model.addAttribute("posts", posts);
return "list-posts";
}
}
@RestController
@RequestMapping("/api/posts")
public class PostRestController {
@GetMapping
public ResponseEntity<List<Post>> listPosts() {
List<Post> posts = postService.findAll();
return ResponseEntity.ok(posts);
}
}
댓글(Comment)
⇒ @Controller와 @RestController 둘 다 사용 가능, 상황에 따라 다름.
- @Controller
- 사용자가 브라우저를 통해 댓글을 포함한 글을 읽을 때 HTML 페이지로 제공되기때문에 댓글을 페이지에 바로 렌더링해서 보여줄 때 적합하다.
- 서버 사이드 렌더링으로, 페이지 로드 시점에 댓글이 함께 로드된다.
- 댓글 데이터를 바로 HTML로 변환하여 클라이언트에 제공하기 때문에 추가적인 JavaScript 작업이 필요 없다.
@Controller
public class PostController {
@GetMapping("/posts/{id}")
public String readPost(@PathVariable Long id, Model model) {
Post post = postService.findById(id);
List<Comment> comments = commentService.findByPostId(id);
model.addAttribute("post", post);
model.addAttribute("comments", comments);
return "view-post";
}
}
- @RestController
- 댓글 데이터를 JSON 형식으로 제공하고, 프론트엔드에서 AJAX를 사용하여 댓글을 비동기적으로 로드하거나 조작할 때 적합하다.
- 댓글을 동적으로 로드하거나 추가적인 인터랙티브 기능을 구현할 때 유용하다.
- 비동기 요청을 통해 필요한 시점에만 댓글을 로드하여 초기 페이지 로딩 시간을 줄일 수 있다.
- 프론트엔드에서 댓글을 동적으로 추가, 수정, 삭제할 수 있어 사용자 경험이 향상된다.
@RestController
@RequestMapping("/api/comments")
public class CommentRestController {
@GetMapping("/post/{postId}")
public ResponseEntity<List<Comment>> getComments(@PathVariable Long postId) {
List<Comment> comments = commentService.findByPostId(postId);
return ResponseEntity.ok(comments);
}
@PostMapping
public ResponseEntity<Comment> addComment(@RequestBody Comment comment) {
Comment savedComment = commentService.save(comment);
return ResponseEntity.status(HttpStatus.CREATED).body(savedComment);
}
}
@Controller | @RestController | |
글 쓰기 | O | |
글 수정 | O | |
글 읽기 | O | |
글 삭제 | O | |
전체 글 조회 |
O | O |
댓글 | O | O |
✅ 무조건적으로 "글 쓰기 기능에는 @Controller를 써야 해!", "글 삭제 기능에는 @RestController를 써야 해!"라고 정해진 규칙이 있는 것은 아니다. 상황에 맞게 @Controller와 @RestController가 각각 언제 사용되는지 잘 이해하고, 그에 따라 적절히 선택하여 사용하면 된다.
'👩🏻💻 About 프로그래밍 > ect' 카테고리의 다른 글
REST, RESTful, REST API (0) | 2024.07.22 |
---|---|
HTTP 메서드 - POST, PUT, GET, PATCH, DELETE (0) | 2024.07.20 |
어노테이션 역할과 사용 용도 (0) | 2024.07.15 |
http 상태에러 401 Unauthorized vs 403 Forbidden (0) | 2024.07.13 |
HTTP 상태 코드의 구조와 종류 (0) | 2024.07.13 |
블로그의 정보
Hello 춘기's world
볼빵빵오춘기