board 라는 게시판 데이터가 쌓이게 되면 두가지의 api가 필요하게 된다.

첫번재는 게시판 목록을 보는 API와 두번째는 하나의 board를 상세하게 보는 API이다.

그래서 여기서는 GET 방식의 두 개의 API를 구현한다.

  • 목록보기: /api/boards
  • 상세보기: /api/board/:id

controller 구현

목록보기와, 상세보기에 해당하는 두개의 API를 구현한다.

라우팅 모듈을 추가한다.

Test

목록보기 api를 테스트한 결과이다. 목록은 여러개의 결과가 오므로 리턴타입이 array가 오게 된다.

상세 보기 api를 테스트한 결과이다. 객체 한개가 리턴되므로 리턴타입이 json 이다.

목록보기 페이지네이션

목록이 많아지면 페이지네이션을 구현해야 한다. 클라이언트에서는 페이지네이션을 구현하기 위해서 3가지 필수요소가 있다.

  • 현재 페이지 넘버
  • 페이지 사이즈
  • 전체 갯수

3번째 페이지에 10개를 가져온다고 하면 아래와 같다.

  • 현재 페이지 넘버: 3
  • 페이지 사이즈: 10
  • 전체 갯수: 서버로 부터 리턴받아야 함.

MariaDB에서는 LIMIT offset, size 라는 쿼리문이 있으므로 위의 값으로 변환하면 아래와 같이 게산된다.

  • offset: (현재 페이저 넘버 – 1) * 페이지 사이즈 (offset는 0부터 시작) => 20
  • size: 페이지 사이즈 => 10

Controller에 page_number와 page_size 두 개의 파라메터를 받고 둘다 null 이 아니면 skip과 take를 계산해서 페이징을 수행하고, 둘 중 하나라도 값이 null 이면 전체 목록을 리턴하도록 한다.

페이징을 테스트하면 다음과 같다.

하지만, 이렇게만 하면 페이지네이션을 구현할 수 있을까? 할수 없다.

왜냐하면 게시판 전체 갯수를 리턴하지 않았기 때문이다.

페이지를 리턴해야 하는 페이징 방식에서는 이것을 하기 위해서 게시판 데이터를 쿼리후에 다시 게시판의 전체 갯수를 쿼리하는 쿼리를 두 번 수행하고 두 개의 쿼리가 모두 성공해야 처리할 수 있도록 transaction 처리를 해야 했다.

물론 지금도 동일하게 처리할 수 있다. 하지만 SPA 프레임웍에서는 REST api를 비동기로 여러번 호출할 수 있으므로 굳이 이것을 동일한 APi로 묶을 필요는 없다. 게시판 갯수만 쿼리하는 별도의 api를 만들어서 제공하면 클라이언트가 두번 쿼리하면 되는것이다. 정답이 있는것이 아니므로 어떤것이 더 확장성과 유지보수성이 좋은것인가를 따져보고 결정하면 된다.

SRP의 원칙처럼 단일 책임을 가지도록 API를 설계하면 필요한 것들으 조합해서 사용하면 되므로 당연이 작게 쪼개는게 확장성이 더 좋다. 게시판 갯수를 리턴하는 api를 추가한다. url 은 /api/board/count 로 GET 방식으로 만든다.

라우팅 모듈에 매핑을 추가한다.

테스트해보면 결과가 나오지 않는다. 왜 그럴까?

앞에서 게시판 상세 보기는 /api/board/:id 이고 카운트 api는 /api/board/count 이다. 스프링에서는 에러가 나지 않았는데 여기서 에러가 나는 이유는 스프링에서는 id 부분을 숫자 타입이라고 지정했기 때문에 스트링 타입이면 count로 매핑하고 숫자이면 게시판 상세보기로 매핑했기 때문이다.

여기서는 둘다 스트링으로 매핑되었기 때문에 /api/board/count 가 게시판 상세보기로 매핑이 되어버려서 결과가 나오지 않는다. 따라서 이 api를 게시판 상세보기 보다 위로 올린다. 그러면 먼저 count를 매핑하고 없으면 아래로 내려가서 매핑하게 된다.