인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

wisehero님의 프로필 이미지

작성한 질문수

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

댓글 최대 2 depth - 목록 API 구현

PathVariable과 RequestParam, Test Code에 관하여

해결된 질문

작성

·

131

0

안녕하세요 쿠케님 강의 잘 듣고 있습니다. 너무 좋아서 팀원들한테도 전파했을 정도입니다. 다들 구매예정이시라고 하네용

 

강의 듣는 도중 궁금점이 생겼는데

 

  1. PathVariable과 RequestParam의 가장 큰 차이점은 단 하나의 유일한 자원의 식별자를 url 경로에서 표현하는가의 여부로 배웠습니다. 그래서 저는 articleId의 경우는 PatVariable로 남겨두었습니다. 이 두가지를 구분하는 쿠케님의 기준이 있으실까용?

  2. 이 강의에서 테스트는 전부 JUnit이 아닌 다른 것들로 수행 중이신데요. 실제로 테스트 코드 작성하실때도 JUnit을 사용하지 않으시나요? 아니면 그냥 강의 진행 편의상 JUnit을 사용하지 않으신건가요?

 

감사합니다.

답변 2

0

쿠케님의 프로필 이미지
쿠케
지식공유자

wisehero님, 안녕하세요!

열심히 잘 수강해주시고 주변에 전파까지 해주고 계시다니 정말 감사합니다!

 

1.

이건 나름의 기준이 있긴 한데, 모든 경우에 일반화해서 사용하는 것도 아니라 말로 풀어내려니 쉽지 않네요..!

 

일단 저도 rest api 원칙을 최대한 따르면서, 자원의 식별자는 PathVariable로 표현하려고 합니다.

그리고 부수적인 파라미터는 RequestParam으로 표현하게 되네요.

 

예시로, 강의에서는 페이지 파라미터를 RequestParam으로 처리했습니다.

어떠한 자원에 대해 필터링/페이징/정렬 등 보조하는 성질의 것은 RequestParam으로 처리하게 되는 것 같네요.

페이징/정렬은 어느 정도 명확하게 다가올 수 있을 것 같은데요,

필터링에 대한건 PathVariable와 RequestParam 중 뭘로 할지 그 기준이 모호하긴 합니다.

 

아래 예시로 부가적인 설명을 해보겠습니다.

예를 들어, 특정 게시판의 게시글 목록 조회 API를 만들 때,

  1. /boards/{boardId}/articles

  2. /articles/boards/{boardId}

  3. /articles?boardId={boardId}

위처럼 세 가지 후보를 생각해볼 수 있을 것 같습니다.

 

일단 2번과 같은 안은 배제하는 편인데요, 각 도메인 모델 간에 포함 관계를 고려했기 때문입니다.

게시글 모델은 게시판 모델을 참조하고 있습니다. 게시글은 게시판 내에 작성되는 개념입니다.

따라서, 게시판이 연관 관계 측면에서 상위에 위치한다고 볼 수 있습니다.

“게시판”의 “게시글”이기 때문에, 게시판을 path에서 먼저 나타내는걸 선호하는 편입니다.

 

그러면, 1번과 3번 두 개의 후보가 남습니다.

둘 사이에서는 도메인을 고려하게 되는 것 같네요.

현재 게시글 마이크로서비스에서 “게시판”과 “게시글” 도메인 모델을 다루고 있습니다.

“게시글” 마이크로서비스라고 명명하였기 때문에, 핵심 도메인은 article로 판단했고,

board는 article을 보조하는 서브 도메인으로 보았습니다.

따라서, 3번과 같이 핵심 도메인을 나타내는 articles를 prefix에 위치하고, 특정 게시판에 대한 필터링은 RequestParam으로 처리해본 것입니다.

3번과 같이 했을 때의 장점은, 만약 userId 필터링 조건이 들어오더라도 RequestParam만 추가하고, API path는 기존 경로를 그대로 유지할 수 있습니다.

boardId와 userId를 게시글과의 포함 관계로 나타내려고 하지 않고, 필터링에 대한 보조 파라미터로 나타내고자 하는 관점이겠네요.

1번처럼 하면, /users/{userId}/articles라는 신규 API path를 추가가 필요합니다.

 

만약, 게시글 마이크로서비스에서 게시글 도메인 뿐만 아니라 해시태그 도메인도 관리해서 “게시글의 해시태그 목록”을 조회한다면,

해시태그는 게시글 내에 포함되는 개념이고, 게시글을 AggregateRoot로 판단할 수도 있으므로,

이 경우에는 articleId를 RequestParam으로 하는게 아니라 /articles/{articleId}/hashtags 와 같이 만들곤 하네요.

 

근데 자원의 포함 관계나 명시적인 가독성 측면에서는 1번이 더욱 명확하게 다가올 때도 있어서, 꼭 3번이 좋다고 말하기는 어려움이 있긴 합니다.

핵심 도메인이 반드시 prefix로 와야 한다는 규칙이 있는 것도 아니거든요. 그냥 개인적으로 이렇게 사용한다는 의미입니다!

필터링으로 볼지, 포함 관계로 볼지 관점이나 상황에 따라서 달라질 수도 있는겁니다!

 

처음부터 계속 언급 드리지만, 위 내용도 개인적인 관점일 뿐이고, 정답은 아닐 것 같습니다.

요구사항이 복잡해지고 api 종류가 많아지다보면, 항상 원칙을 따르는게 쉽지 않더라고요.

사람마다 생각하는 방식이 다를 수도 있는 것이고요.

사실 크게 문제 될 부분이 아니면, 팀에서 지향하는 바를 따라가거나, 위와 같은 나름의 규칙으로 만들게 되는 것 같네요! 

 

 

  1.  

강의에서 모든 테스트코드는 JUnit을 사용하고 있고, 실무에서도 JUnit을 사용합니다!

@Test 애노테이션을 설정하는 것도 JUnit의 기능입니다.

사용하지 않는다고 생각하신 부분이 어떤 것일까요?!

RestClient 직접 정의해서 로컬에 실행된 서버 애플리케이션 호출하는 부분 말씀하시는 것이려나요?!

웹 페이지와 같이 프론트 구성은 따로 진행하지 않았기 때문에,

만들어진 API의 동작을 실제로 호출해서 눈으로 결과를 확인해보기 위해 이처럼 한 것이고,

Postman 등 다른 도구를 써볼까 하다가 그냥 코드로 만들어본 것입니다!

 

혹시 더 궁금한 점 있으시면 편히 문의 주세요!

wisehero님의 프로필 이미지
wisehero
질문자

답변 감사드립니다. 1번에 관련해서는 항상 고민이 많았고 팀원들과도 계속 이야기하는 중이었는데 좀 더 도메인 관점에서 바라보는 시각은 제가 부족했던 것 같습니다. 인사이트 감사드립니다.

아 두 번째는 단순히 MockMvc나 @WebMvcTest와 같은 어노테이션, 혹은 @SpringBootTest와 같은 어노테이션을 쓰지 않아서 JUnit을 쓰지 않는다는 착각을 하고 있었네요! 제가 언급한 것들은 엄연히 테스트 프레임워크 내에서 사용할 수 있는 보조도구였는데 말이죠... 보통은 저것들이 따라오다보니 뭉뚱그려 JUnit이라고 암묵적으로 생각하고 있었던 것 같습니다. 보통의 테스트 코드와 관련된 강의에서 진행하는 방식들과는 조금 다른 방식으로 테스트 코드를 구성하셔서 생겼던 의문이었습니다!

쿠케님의 프로필 이미지
쿠케
지식공유자

테스트 디렉토리에서 RestClient로 서버 호출하는 부분은, 그냥 코드로 서버 애플리케이션 API 호출하여 실행 확인해본 것이라고 생각하면 조금 더 이해가 편할 것 같네요!

개인적으로 통합테스트를 많이 작성하는 편은 아니긴 합니다.

뒷부분에서는 단위 테스트를 많이 작성하게 될겁니다!

테스트 관련하여 이전에 다른 분께 이러한 질문도 받았어서 참고해보셔도 좋을 것 같네요.

https://www.inflearn.com/community/questions/1529337

화이팅입니다!

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. wisehero님.

강의를 즐기고 계셔서 다행입니다! PathVariable과 RequestParam, 그리고 테스트 코드 작성에 대해 궁금하신 점을 설명드리겠습니다.

1. PathVariable과 RequestParam의 차이

  • PathVariable: 주로 URL 경로의 일부로 사용됩니다. 고유한 자원을 식별할 때 적합합니다. 예를 들어, 특정 게시물의 ID를 URL 경로의 일부로 사용하는 경우입니다. /articles/{articleId}와 같은 형식이 이에 해당합니다.

  • RequestParam: 주로 쿼리 파라미터로 사용되며, URL에서 자원이 아닌 데이터의 일부를 전달할 때 적합합니다. 주로 필터링, 정렬 등의 목적으로 사용됩니다. 예를 들어, /articles?page=2&size=10의 형태로 요청을 보낼 때 사용합니다.

쿠케님의 기준 역시 보편적인 이해와 크게 다르지 않을 것으로 보입니다. 자원의 식별자가 URL 경로에 자연스럽게 포함되는 경우에는 PathVariable을, 더 잘게 쪼개진 데이터나 옵션 사항을 전달할 때는 RequestParam을 사용하는 게 일반적입니다.

2. JUnit 사용 여부

  • JUnit과 테스트: 쿠케님께서 JUnit 대신 다른 프레임워크나 방법으로 테스트를 진행하고 있다면, 이는 강의의 특정 요구사항이나 편의에 따른 것일 수 있습니다. JUnit은 자바 생태계에서 가장 널리 사용되는 테스트 프레임워크입니다만, 테스트 자동화나 병렬 테스트, 더 나은 리포팅 등 특정 목적에 맞는 툴을 선택하실 수도 있습니다.

  • 현실에서는 다양한 테스트 프레임워크를 조합하여 사용하기도 하며, 프로젝트의 요구에 따라 JUnit, TestNG, Spock 등이 선택될 수 있습니다.

질문에 대해 좀 더 깊이 있는 정보를 원하신다면, 기존 질문과 답변에서 추가적인 사례를 참고하실 수 있습니다:

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

wisehero님의 프로필 이미지

작성한 질문수

질문하기