Hello

@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가 각각 언제 사용되는지 잘 이해하고, 그에 따라 적절히 선택하여 사용하면 된다.

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기