Programming/Spring framework

MVC vs RestController, 서버사이드 렌더링과 클라이언트 사이드 렌더링(feat. thymleaf, React) 2023-05-16 화요일

최동훈1 2023. 5. 16. 19:00

Spotify Api 를 사용하는 프로젝트를 하는중 머릿속에 스쳐가는 의문점이 떠올랐다. 

발단은 이랬다. 배포를 하기 위해서는 서버의 코드와 클라이언트의 코드가 분리되어있을텐데 어떻게 AWS EC2로 배포를 하는거지?

나는 이것에 대한 정답을 MVC구조와 RestController 구조에서 찾게 되었다. 우선 내가 그토록 지겹도록 배웠던 전통적인 스프링 MVC 구조를 설명하자면 Controller 의 return 값으로 view page를 반환하면, 해당 Controller에서 Model.AddAttribute를 통해 받았던, Model 값을 뷰 템플릿 엔진을 통해 HTML 의 화면에 data를 바인딩(데이터를 입력해주는 것) 해주고 그 결과 페이지인 .html 페이지를 HTTP response를 통하여 클라이언트에게 보내는 것이다. 

SSR에서의 MVC 구조

 그리고 앞서 말한 data를 HTML에 바인딩하는 과정, 즉 렌더링 과정을 해주는 뷰 템플릿 엔진이 그 유명한 JSP,Thymleaf 이다. 즉, MVC 구조와 RestController 구조의 가장 큰 차이는 Controller의 리턴 값에 존재한다. 아래의 코드를 보자

@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
 private MemberRepository memberRepository = MemberRepository.getInstance();
 @GetMapping("/new-form")
 public String newForm() {
 return "new-form";
 }
 @PostMapping("/save")
 public String save(
 @RequestParam("username") String username,
 @RequestParam("age") int age,
 Model model) {
 Member member = new Member(username, age);
 memberRepository.save(member);
 model.addAttribute("member", member);
 return "save-result";
 }
 @GetMapping
 public String members(Model model) {
 List<Member> members = memberRepository.findAll();
 model.addAttribute("members", members);
 return "members";
 }
}

 

이렇게 return 값으로 view.html 의 페이지 이름을 주게 되면, 스프링은 자동으로 resource/templates/{view이름}.html에 존재하는 view 파일로 model에 담긴 data를 바인딩 시킨후, HTTP response 메세지 Content-Type" 헤더는 "text/html" 로 클라이언트에 화면 자체를 보내준다. 이때 model에 담긴 data를 HTML에 담아주는 것을 뷰 템플릿 엔진 이라하고 대표적으로 JSP, Thymleaf 등이 있다.

그러나 RestController를 사용할경우 이야기가 달라진다. 아래의 코드를 보자.

@RestController
public class SpotifyController {
    SpotifyApi spotifyApi = new SpotifyApi.Builder()
            .setAccessToken(SpotifyConfig.accessToken())
            //accessToken()은 SpotifyConfig 에서 발급함
            .build();

    @Autowired
    SpotifyService spotifyService =new SpotifyService();

    @GetMapping("/search/{trackname}")
    public List<SearchResponseDto> searchTracksByTrackname(@PathVariable String trackname) throws IOException, ParseException, SpotifyWebApiException {


        return spotifyService.SearchByTrackname(trackname);
    }

    @GetMapping("/search/{artist}/{trackname}")
    public List<SearchResponseDto> searchTracksByTracknameAndArtist(@PathVariable String trackname,@PathVariable String artist) throws IOException, ParseException, SpotifyWebApiException {


        return spotifyService.SearchByTracknameAndArtist(trackname,artist);
    }

}

 

리턴값으로 객체가 주어진다. 참고로 spotifyService.SearchByTrackname(trackname) 는 리스트 형식의 반환값이다. 스프링에서는 JACKSON 이라는 라이브러리를 사용하면 이렇게 Controller의 리턴 값으로 객체가 들어오면, view를 거치지 않고, HTTP Response 메세지 바디에 "Content/Type" JSON 이라는 형식으로 바로 "콱" 넣어서 HTTP response를 클라이언트에 보낸다.  이러면 .html 과 같은 화면이 아닌 JSON 이라는 형식으로 이루어진 data 들만 클라이언트로 전송되는 것이다.

여기서 바로 CSR(Client Side Rendering) 과 SSR(ServerSideRendering) 이 나온다. 내가 RestController 를 사용해서 Client에 json data를 보내면 클라이언트는 이 data를 화면에 렌더링해서 최종적으로 사용자에게 보여주는 것이다. 이때 사용되는 라이브러리가 React 이다. 

즉, 화면을 모두 서버에서 만들어서 뿌려주는 경우, 배포를 서버 코드만 하면 되지만, 만약 CSR을 사용해서 백엔드는 단순 API만 개발할 경우에는 클라이언트 코드와 백엔드 코두 둘다 배포해서 서로 API 통신하는 방식으로 배포를 진행해야 한다.

관련해서 김영한 님의 답변을 첨부하겠다.

 

질문내용 :

성능 문제로 템플릿 엔진보다는 웹 프레임워크 vue.js react.js angular.js를 쓴다고 들었습니다. 여기 강의에서 thymeleaf 템플릿 엔진을 사용했는데, spring에서 템플릿 엔진을 꼭 써야하는지 아니면 간단하게 예제로써만 사용하고 나중에는 react.js vue.js angular.js같은 웹 프레임워크를 사용하는 지 궁금합니다.

 

답변:

안녕하세요. ulsandonghun님 좋은 질문입니다.

웹 애플리케이션 개발은 크게 2가지 렌더링 방식이 있습니다.

1. 서버 사이드 렌더링

설명: 서버에서 완전한 HTML을 만들어서 내려줍니다. 대표적으로 jsp, thymeleaf, velocity, freemarker가 있습니다.

장점: 단순하고, 학습 곡선이 낮습니다. 백엔드 개발자도 쉽게 개발할 수 있습니다.

단점: 동적이면서 복잡한 화면을 만들기 어렵습니다.

 

2. 클라이언트 사이드 렌더링

설명: 서버는 API만 제공하고, 자바스크립트 프레임워크가 템플릿과 서버 API 응답 결과를 조합해서 HTML 화면을 동적으로 만듭니다. 대표적으로 react, vue.js, angularJS 등이 있습니다.

장점: 동적이고, 복잡한 화면을 만들기 좋습니다.

단점: 공부할 분량이 매우 많습니다. 자바스크립트에 능숙해야 합니다. 웹 프론트엔드 개발자라는 전문 분야가 있습니다.

 

정리

클라이언트 사이드 렌더링은 웹 프론트엔드 개발자라는 전문 분야가 있을 정도로 학습해야 할 내용이 많습니다. 저희 회사를 비롯한 대부분의 회사가 백엔드 서버 개발자와 웹 프론트엔드 개발자를 별도로 채용합니다.

실무에서는 서버 사이드 렌더링도 필요하고 클라이언트 사이드 렌더링도 필요합니다. 단순하고 정적인 화면이라면 서버 사이드 렌더링 기술로 개발을 금방 끝낼 수 있습니다.

제가 추천하는 방법은 먼저 서버 사이드 렌더링 기술을 하나라도 배우고, 그 다음에 여유가 되면 클라이언트 사이드 렌더링 기술은 옵션으로 배우시는 것을 추천드립니다.

그래서 선택지를 드리자면^^

1. 자바스크립트에 자신있고, 완전 풀스택으로 갈것이다. = react + typescript

2. 백엔드 개발이 좋고, 스프링이 좋은데, 어쩔 수 없을 때 화면을 찍겠다. = thymeleaf

3. 레거시 하는 회사에 입사해야 한다. = jsp (ㅠㅠ)

4. velocity는 그냥 그걸 사용하는 회사에 입사하고 고민해도 됩니다. ㅎㅎ (쉬워서요 ㅎㅎ)

감사합니다

 

PS) 위에 @RestController 는 @ResponseBody와 @Controller가 결합된 애너테이션이다.  

 

공부 후기.

요새 너무 학과 공부에 치여서 블로그에 집중하지 못한거 같다. 6전공 1교양 살려줘 ㅠㅠㅠ 죽을거 같다.  진짜 하루종일 도서관 다니면서 수업 따라가랴 프로젝트 하랴 바쁜 하루를 보내고 있다. 그래도 고생하면서 사는만큼 나의

끈기가 값이되어 나의 삶이 행복해지길 바란다.