S3U1 [Spring MVC] API 계층 회고

    반응형

    [Spring MVC 아키텍처]

    🥑 Spring Framework를 구성하는 모듈 중 서블릿 API를 기반으로 웹 요청을 처리하는 모듈이 있다. 바로 spring-webmvc이다. 지난 회고에서도 살짝 정리해보았지만, 자체 MVC 프레임워크를 제공하고 웹을 담당하는 모듈이다. 클라이언트의 요청을 처리해준다고 볼 수 있겠다. 그렇다면 MVC는 무엇을 의미할까?

    Model: 클라이언트에게 돌려주는 작업 처리 결과 데이터이다.

    View: Model 데이터를 이용해서 클라이언트 화면에 보여지는 리소스를 제공한다. view 형태에는 여러가지가 있는데, HTML페이지(JSP와 같은 SSR에서 사용된다) / PDF나  Excel 등의 문서 / XML, JSON 등 특정 포맷으로 변환된 형태(주로 CSR) 크게 세 가지로 나눌 수 있다. CSR을 위주로 학습하고 있는 나는 JSON 형태의 View를 다룬다고 볼 수 있겠다.

    Controller: 클라이언트 요청을 받는 엔드포인트이다. 하지만 엄밀히 말하자면 Spring MVC 흐름에서 요청을 가장 먼저 받는 곳은 Controller가 아니다.요청이 들어오면 (1) DispatcherServlet에서 요청을 받아 (2) HandlerMapping을 통해 Controller 정보를 얻고, 그 정보를 토대로 (3) HandlerAdapter에게 Controller 호출을 위임하고, (4) Controller를 호출해 요청을 처리한다(애플리케이션 내부 처리). 이를 통해 HandlerAapter로 반환된 Mdoel 데이터 + View 이름을 DispatcherServlet에게 반환하면 그 데이터를 토대로 (5) ViewResolver를 통해 View 정보를 얻는다. 반환된 (6) View에 응답 생성을 요청하고, 반환받은 응답 데이터를 웹브라우저에게 최종적으로 반환한다.DispatcherServlet이 중간에서 계속해서 다른 요소들과 상호작용하며 웹 브라우저와 요청과 응답을 직접적으로 관리하는 것이다.

     

    원래 MVC에 대해서 알고 있느냐 물으면 알고 있다 대답하고, 모델, 뷰, 컨트롤러 각각의 역할을 이야기할 수 있었다. 이 챕터를 학습하면서 이제는 MVC 동작 흐름을 보다 구체적으로 설명할 수 있게 되었다. 구체적으로 어떤 클래스가 어떻게 처리를 하는지까지는 살펴보지 못 했지만... 점점 더 수준이 깊어지고 있으니 더 구체적으로 알게되는 날이 곧 다가오지 않을까!? 물론이다🥹

    그런데 조금 헷갈렸던 점은 JSP 프로그래밍을 할 때는 Model과 View의 구분이 명확했는데 Spring에서는 조금 경계가 모호했다고 해야할까? 어쨌든 응답으로 나가는 건 데이터인데 말이다. 내가 이해한 바로는 Model 데이터는 자바 객체이고 JSON으로 변환된 형태의 데이터를 View라고 볼 수 있을 것 같은데, 어쨌든 View는 화면을 그리기 위한 리소스로 여겨지기 때문에 이렇게 생각했다. 이건 다시 한 번 체크를 해보아야겠다.

    회고를 작성하면서 알게 된 내용인데 전통적인 MVC(그러니까 JSP와 같은 방식인 것 같다) 방식에서는 @Controller를 붙여주었을 때 Controller로부터 ViewName이 반환된다. (생각해보니 그랬었다) 하지만 @RestController를 붙이면 Controller에서 나올 때 응답 객체 데이터는 ReponseEntity로 감싸져 나오고, 최종적으로 HttpMessageConverter를 거쳐 JSON으로 변환된 데이터가 리턴된다. 그러니까 @RestController는 @Controller + @ResponseBody의 동작과 동일하다고 볼 수 있다고 한다. 그렇다면 @RestController가 붙은 경우에는 ViewResolver 대신 HttpMessageConverter가 작동한다고 보아도 되는 것인지를 함께 확인해야겠다. 그리고 @ResponseBody로 인해 Serialize가 이루어지는 것이라면 HandlerAdapter로 반환되기 전에 HttpMessageConverter가 동작하는 것인지도 함께 확인해야겠다. Jackson2Converter 이런 게 있었는데... 분명 한 번 설명을 들었는데도 모르겠다^-ㅠㅋ


    [Controller]

    🥑 Controller는 위에서 설명했듯이 웹 애플리케이션에서 클라이언트의 요청을 받는 엔드포인트이다. 계층 구조로 이야기 하면 API 계층이라고 할 수 있다.

    Controller에는 @RestController를 붙여준다.(RESTful 웹 서비스 기준이다) @Component를 포함하고 있어 @Component를 명시하지 않아도 Spring Bean 등록이 가능하고, @Controller와 달리 @ResponseBody를 포함하고 있어 JSON 데이터로의 변환을 다루는 것이 가능해진다.  또 다른 대표적인 애너테이션에는 @RequestMapping("/BaseUrl")이 있다. 클라이언트 요청과 핸들러 메서드를 매핑해주기 위함이고, 이게 없으면 404가 뜰 것이다... BaseUrl은 해당 클래스 전체에서 사용하는 공통 URL을 적어준다. 주로 member와 같은 리소스명이다. 참고로 PathVariable에 대한 유효성 검사를 위해서는 @Validated도 붙여주어야 한다.

    그 뒤에는 직접 요청을 처리하는 핸들러 메서드를 작성하는데, 꼭 붙여야 하는 애너테이션은 @GetMapping, @PostMapping 등의 http 메서드를 명시한 Mapping 애너테이션이다. @DeleteMapping("/{member-id}")와 같이 PathVariable로 사용되는 자원을 적어줄 수도 있다. 참고로 수정하는 메서드에 @PostMapping을 붙여주어도 문제없이 동작하지만 "수정"이라는 행위를 꼭 명시해주어야 REST하기 때문에() 알맞은 애너테이션을 골라 사용해야 할 것이다!

     

    지금 와서 생각해보면 Rest API Controller니까 @RestController 붙이고 return ResponseEntity 돼있으니까 나도 쓰고 객체 리턴하니까 하고... 이런 식으로 기존 코드를 따라하거나 시키는대로 했던 기억이 가장 많이 난다. 그러니 스스로 깊은 이해를 하지도 못 했고, 하려고 하지도 않았던 것 같다.(급 반성) 그래도! 이번 Spring을 학습하면서 Bean Container를 비롯해 Spring에서의 객체 관리에 대해 깊이 알고 나니 애너테이션 하나하나도 해석이 쉬워지고 그래서인지 더 흥미롭다. 넘나 기뻐


    [DTO(Data Transfer Object)]

    🥑 DTO는 직역하면 데이터를 옮겨주는 객체이다. 요청/응답 데이터 전송 시 DTO를 사용하면 코드가 한층 간결해진다. 그 이유는 @RequestParam을 작성해서 하나하나 받아주지 않아도 되는 것도 있지만, DTO 내부에 애너테이션을 잘 작성해주면 알아서 유효성 검사를 실시해주기 때문이다!

    DTO를 사용하기 위해서는 @RequestBody를 달아줘야 하는데 그러면 HttpMessageConverter를 통해 JSON -> Java 객체로 자동 변환(역직렬화, deserialization)이 이루어진다. 

     

    DTO는 딱히 어려운 건 없었다. Mapper를 통해서 도메인 객체와 분리를 하는 것도 재미있었다. (미래에서 왔습니다) 유효성 검사를 구현하는 부분에서 나 나름대로 뻘짓하느라 시간을 많이 쓰긴 했지만 그래도 어느정도 만족스러운 결과를 냈으니까 오히려 좋았다! 실습도 재미있게 진행했고 얼른 다음 유닛들을 배우고 싶어지는 순간이었다ㅎㅎ


    🎮Unit 1. API 계층을 마치고!

    본격적으로 API 쪽으로 들어오니까 확실히 실습이 더 재미있어졌다. 위에 챕터 후기에서 작성한대로 나는 원래 작성되어있는 코드를 레퍼런스 삼아 따라치는 코딩만 주구장창 해왔던 것 같다. 말로는 배우는 개발자 성장하는 개발자라고 했으면서 정 반대로 행동하고 있었다는 느낌이 든다😓 그래도 요즘 가장 좋은 건 내가 딱 원했던대로 내 지식을 채워가고 있다는 점!? 코드스테이츠 지원서에도 구멍 뚫린 지식을 동료들과 함께 단단히 유지보수 하고 싶다고 적었었는데(ㅋㅋ) 나름 잘 되어가고 있는 것 같아서 정말 기쁘다. 그래서인지 모르겠는데 예전에는 프로젝트 구상을 하면 잘 안 되었는데 지금은 아 이것도 해보고싶다 아 저것도 해보고싶다 하는 게 늘어나고 있다. 그래서 마음먹은 게 학습 내용을 따라서 같이 적용해볼 수 있는 나만의 프로젝트를 하나 생성해야겠다는 것이다. 원래는 있던 프로젝트를 좀 리팩토링하면서 진행해보고 싶었는데, 그렇게 되면 좀 복잡해져서 시간을 오히려 더 쓸 수도 있을 것 같아 새로 시작하기로 했다. 주제는 조금 더 생각해봐야겠지만, 학습과 함께 가면서 배운 기능들을 구현해보기 위한 것이다 보니 아무리 흔한 주제, 간단한 기능이라도 "제대로" 구현해낼 수 있을 수만 있다면 어떤 게 되든 괜찮을 것 같다. 지금 왜이렇게 의욕 넘치는 거,,, 유닛이 진행될 수록 텐션이 떨어져가는 나를 발견할 수도 있겠다. 사실 회고를 완성한 지금 JDBC를 시작한 상태이긴 하다^^;; 이대로만 긍적적으로 뭐든 해낼 수 있으면 좋겠다... 아차차 심화로 학습한 Rest Client는 따로 글을 써보고싶다. API 계층 회고 끝

     

    반응형

    댓글