[코드로 배우는 스프링 웹 프로젝트 개정판] 4장 정리

REST 방식을 이용하여 데이터를 전송하고 처리하는 방법에 대해 설명하였습니다. REST는 URI를 통해 리소스를 대표하며, 스프링은 이를 위해 다양한 어노테이션을 지원합니다. 또한, REST 방식의 데이터 교환은 GET/POST 외에도 다양한 방식으로 데이터를 전달합니다. 또한, Ajax를 이용한 댓글 처리 방법과 이를 위한 영속 영역 설정, 이벤트 처리와 HTML 처리, 댓글의 페이징 처리 방법에 대해 설명하였습니다.
DriedPollack's avatar
Mar 20, 2024
[코드로 배우는 스프링 웹 프로젝트 개정판] 4장 정리

🌼REST 방식으로 전환

💡핵심 키워드

  • REST는 ‘Representational State Transfer’의 약어로 하나의 URI는 하나의 고유한 리소스를 대표하도록 설계된다는 개념에 전송방식을 결합해서 원하는 작업을 지정한다.
  • 스프링은 데이터 처리를 위한 여러 종류의 어노테이션을 지원한다.

@RestController

  • @RestController는 메서드의 리턴 타입으로 사용자가 정의한 클래스 타입을 사용할 수 있고, 이를 JSON이나 XML로 자동으로 처리할 수 있다.
  • JSP와 달리 순수한 데이터를 반환하는 형태이므로 다양한 형태의 데이터를 전송할 수 있다. 주로 많이 사용하는 형태는 일반 문자열이나 JSON, XML 등을 사용한다.
    • @GetMapping에 사용된 procedures 속성은 해당 메서드가 생성하는 MINE 타입을 의미한다. 문자열로 직접 지정할 수도 있고, 메서드 내의 MediaType이라는 클래스를 이용할 수도 있다.
    • @GetMapping(value = "/getText", produces = "text/plain; charset=UTF-8") public String getText(){ log.info("MINE TYPE: " + MediaType.TEXT_PLAIN_VALUE); return "안녕하세요"; }
    • 객체를 반환하는 작업은 JSON이나 XML을 이용한다.
  • REST 방식으로 호출되는 경우는 화면 자체가 아니라 데이터 자체를 전송하는 방식으로 처리되기 때문에 데이터를 요청한 쪽에서는 정상적인 데이터인지 비정상적인 데이터인지 구분할 수 있는 확실한 방법을 제공해야 한다.
    • ResponseEntity는 데이터와 함께 HTTP 헤더의 상태 메시지 등을 같이 전달하는 용도로 사용한다.
  • @PathVariable은 일반 컨트롤러에서도 사용이 가능하지만 REST 방식에서 자주 사용된다. URL 경로의 일부를 파라미터로 사용할 때 이용한다.
  • @RequestBody는 JSON 데이터를 원하는 타입의 객체로 변환해야 하는 경우에 주로 사용한다.

REST 방식의 테스트

  • @RestController를 쉽게 테스트할 수 있는 방법은 주로 REST 방식의 데이터를 전송하는 툴을 이용하거나, JUnit과 spring-test를 이용해서 테스트하는 방식이다.
    • postman과 같은 도구를 통해 테스트를 할 수 있다.

다양한 전송방식

  • REST 방식의 데이터 교환에서 가장 특이한 점은 기존의 GET/POST 외에 다양한 방식으로 데이터를 전달한다는 점이다.
    • 작업
      전송방식
      Create
      POST
      Read
      Get
      Update
      PUT
      Delete
      DELETE
    • POST 방식도 그렇지만 PUT, DELETE 방식은 브라우저에서 테스트하기 쉽지 않기 때문에 개발 시 JUnit이나 다른 테스트 도구를 이용해서 개발해야 한다.
 

🌼Ajax 댓글 처리

💡핵심 키워드

  • REST 방식을 가장 많이 사용하는 형태는 브라우저나 모바일 App 등에서 Ajax를 이용해서 호출하는 것이다.

댓글 처리를 위한 영속 영역

  • MyBatis는 두 개 이상의 데이터를 파라미터로 전달하기 위해서는 세 가지 방식이 있다.
    • 별도의 객체로 구성하거나
    • Map을 이용하거나
    • @Param을 이용해서 이름을 사용하는 방식
  • 이 중 @Param을 이용하는 방식이 가장 간단하다.
    • @Param의 속성값은 MyBatis에서 SQL을 이용할 때 #{} 의 이름으로 사용이 가능하다.

등록 작업과 테스트

  • REST 방식으로 처리할 때 주의해야 하는 점은 브라우저나 외부에서 서버를 호출할 때 데이터의 포맷과 서버에서 보내주는 데이터의 타입을 명확히 설계해야 하는 것이다.
    • 댓글 등록은 @PostMapping으로 POST 방식으로만 동작하도록 설계하고, consumesproduces를 이용해서 JSON 방식의 데이터만 처리하도록 하고, 문자열을 반환하도록 설계한다.
    • 파라미터는 @RequestBody를 적용해서 JSON 데이터를 원하는 타입으로 변환하도록 지정한다.
    • 만약 파라미터가 원하는 타입의 값이 들어가지 않았을 경우, HttpStatus.INTERNAL_SERVER_ERROR를 통해 상태 코드를 출력시킬 수 있다.

JavaScript 준비

  • 화면에서 사용되는 JQuery는 막강한 기능과 다양한 플러그인을 통해서 많은 프로젝트에서 기본으로 사용된다. 특히 Ajax를 이용하는 경우에는 jQuery의 함수를 이용해서 쉽게 처리할 수 있다.
  • 모듈 패턴은 Java의 클래스처럼 JavaScript를 이용해서 메서드를 가지는 객체를 구성하는 것이다. JavaScript의 즉시 실행함수와 {} 를 이용해서 객체를 구성한다.
    • JavaScript의 즉시 실행함수는 () 안에 함수를 선언하고 바깥쪽에서 실행한다. 즉시 실행함수는 함수의 실행 결과가 바깥쪽에 선언된 변수에 할당된다.
    • jQuery의 $(document).ready(..) 는 한 페이지 내에서 여러 번 나와도 상관없기 때문에 기존의 JavaScript 코드를 수정하지 않으려면 별도의 <script> 태그로 분리해야 한다.
  • Ajax 호출은 감춰져 있기 때문에 코드를 좀 더 깔끔하게 작성할 수 있다.
    • 파라미터로 callback과 error를 함수로 받을 수 있다. 만일 Ajax 호출이 성공하고, callback 값으로 적절한 함수가 존재한다면 해당 함수를 호출해서 결과를 반영할 수 있다.
    • JavaScript는 함수의 파라미터 개수를 일치시키지 않아도 유연하게 동작한다.
  • jQuery의 getJSON()을 이용해서 JSON 타입의 데이터를 가져올 수 있다. 이 경우 JSON 형태가 필요하므로 URL 호출 시 확장자를 .json으로 요구한다.
  • 댓글 삭제는 DELETE 방식을 통해 해당 URL을 호출해야 하므로 $.ajax()를 이용해서 구체적으로 type 속성을 delete로 지정한다.

이벤트 처리와 HTML 처리

  • 화면에서 버튼 등에서 발생하는 이벤트를 감지하고 Ajax 호출의 결과를 화면에 반영할 수 있다.
  • XML이나 JSON 형태로 데이터를 받을 때는 순수하게 숫자로 표현하는 시간 값이 나오게 되어있으므로 화면에서 포맷을 처리해야 한다.
  • .closest("div")를 통해 현재 엘리먼트에서 가장 가까운 조상을 반환할 수 있다.
  • .hide()를 통해 필요 없는 항목들은 안 보이게 처리할 수 있다.
  • DOM에서 이벤트 리스너를 등록하는 것은 반드시 해당 DOM 요소가 존재해야만 가능하다. 동적으로 Ajax를 통해서 태그를 만들고 난 후 이벤트를 등록하는 경우, 일반적인 방식이 아닌 이벤트 위임의 형태로 작성해야 한다.
    • 이벤트 위임이란 이벤트를 동적으로 생성되는 요소가 아닌 이미 존재하는 요소에 이벤트를 걸어주고, 나중에 이벤트의 대상을 변경해 주는 방식이다. jQuery는 on()을 이용해서 처리할 수 있다.
    • 이 책의 경우 동적으로 만들어지는 <li>태그의 조상인 <ul>태그의 클래스를 이용해서 이벤트를 걸었다.

댓글의 페이징 처리

  • 댓글의 숫자가 많다면 데이터베이스에서 많은 양의 데이터를 가져와야 하고, 이는 성능상의 문제를 가져올 수 있다. 일반적으로는 이런 문제를 페이징 처리를 이용해서 처리한다.
  • 댓글의 경우 우선적으로 고려해야 하는 것은 댓글 테이블을 접근할 때 댓글의 번호가 중심이 아니라, 게시글의 번호가 중심이 된다는 것이다.
    • 이 경우 중간에 있는 다른 게시글의 번호는 건너뛰어 가면서 특정 게시글의 댓글을 찾아야 하므로 성능에 문제가 생긴다.
    • 이를 해결하기 위해 게시글의 번호에 맞게 댓글들을 모아둘 수 있다. 이것이 인덱스를 생성하는 것이다.
    • 인덱스는 정렬을 피할 수 있기 때문에 FULL SCAN이 아닌 RANGE SCAN을 할 수 있다.
  • 댓글의 화면 처리는 다음과 같은 방식으로 처리한다.
    • 게시글을 조회하는 페이지에 들어오면 기본적으로 가장 오래된 댓글들을 가져와서 1페이지에 보여준다.
    • 1페이지의 게시글을 가져올 때 해당 게시글의 댓글의 숫자를 파악해서 댓글의 페이지 번호를 출력한다.
    • 댓글이 추가되면 댓글의 숫자만을 가져와서 최종 페이지를 찾아서 이동한다.
    • 댓글의 수정과 삭제 후에는 다시 동일 페이지를 호출한다.
 

🏁결론

서버는 브라우저나 모바일에서 필요한 순수한 데이터만들 전달하는 API 서버의 형태로 변화하고 있다. 예를 들어, 검색 API 서버는 검색의 결과를 XML이나 JSON의 형태로 전달하고, 브라우저나 모바일에서는 이를 가공해서 사용자에게 보여주는 방식을 취한다.
이러한 환경에 대비할 수 있는 방법으로는 REST 방식을 사용하는 것과, Ajax를 이용하는 방법 등이 있다.
Share article

More articles

See more posts
RSSPowered by inblog