올바른 URL 설계 : 1) Query string과 Path Variable 이해하기

Joey Lee·2020년 6월 2일
31

Django

목록 보기
13/23

1. Path Variable과 Query Parameter

이 글은 When Should You Use Path Variable and Query Parameter?란 영문글을 한글로 요약 정리한 것입니다. 자세한 내용은 원문을 참고해 주세요.

웹에서 특정 데이터를 전송하고 받기 위해서는 어디(End-point)에 요청할 것인가는 중요한 문제이다. 우리는 데이터를 전송하기 위해 GET, 전송 받기 위해 POST 방식을 쓰는데 이 때 각각의 경로(End-point)를 어떻게 정하는 것이 좋을까.

이에 대한 아이디어는 REST API라는 개념을 통해서 알 수 있다. 하지만 그 이전에 중요하게 알아둬야 할 개념이 Path Variable과 Query Parameter이다. 이 각각의 개념은 무엇이고, 어떤 경우에 써야 되는 것일까 알아보자.

1) Query string

/users?id=123 # Fetch a user who has id of 123 

위에서 보는 것처럼 ? 뒤에 id란 변수에 값을 담아 백엔드에 전달하는 방식이 Query string이다. users에 담긴 정보 중 id 123번의 자료를 달라는 요청이다.

2) Path Variable

/users/123 # Fetch a user who has id 123

위와 동일한 요청을 경로를 지정하여 요청할 수도 있는데 이것을 Path Variable이라고 한다.

3) Query string과 Path variable은 각각 언제 쓰면 좋은가?

일반적으로 우리가 어떤 자원(데이터)의 위치를 특정해서 보여줘야 할 경우 Path variable을 쓰고, 정렬하거나 필터해서 보여줘야 할 경우에 Query parameter를 쓴다. 아래가 바로 그렇게 적용한 사례이다.

/users # Fetch a list of users
/users?occupation=programer # Fetch a list of programer user
/users/123 # Fetch a user who has id 123

위의 방식으로 우리는 어디에 어떤 데이터(명사)를 요청하는 것인지 명확하게 정의할 수 있다. 하지만, 그 데이터를 가지고 뭘 하자는 것인지 동사는 빠져있다. 그 동사 역할을 하는 것이 GET, POST, PUT, DELETE 메소드이다.

즉, Query string과 Path variable이 이들 메소드와 결합함으로써 "특정 데이터"에 대한 CRUD 프로세스를 추가의 엔드포인트 없이 완결 지울 수 있게 되는 것인다.
(가령, users/create 혹은 users?action=create를 굳이 명시해 줄 필요가 없다.)

/users [GET] # Fetch a list of users
/users [POST] # Create new user
/users/123 [PUT] # Update user
/users/123 [DELETE] # remove user

물론 위와 같은 규칙을 지키지 않더라도 잘 돌아가는 API를 만들 수 있다. 하지만 지키지 않을 경우 서비스 엔드포인트는 복잡해 지고, 개발자간/외부와 커뮤니케이션 코스트가 높아져 큰 잠재적 손실을 초래할 수 있으니 이 규칙은 잘 지켜서 사용하는 것이 필수라 하겠다.

2. 코드와 테스트로 이해하기

1) Query string

장고는 HTTP request 안에 request.GET 그리고 request.POST 객체로 쿼리 딕셔너리를 가져올 수 있다.

[views.py]

class CategoryView(View):
	def get(self, request):
		category = request.GET.get('category_id', None)

View 클래스에서 위와 같이 작성하면 category_id란 값을 가져올 수 있다.

테스트를 위해 httpie에서 http -v url category_id==4를 입력하면, 장고의 request.GET에서는 <QueryDict: {'category_id': 4}가 들어가게 되고, request 헤더에 엔드포인트 url로 /product?category=4가 찍히게 된다.

만약 테스트를 포스트맨을 통해서 한다면, 파라미터 탭에 키와 밸류를 넣어주면 됩니다.

2) Path variable

[views.py]

class ProductView(View):
	def get(self, request, product_id):
		product = Product.objects.filter(id=product_id).values()

[urls.py]

urlpatterns = [
    path('product/<int:product_id>', ProductView.as_view())
]

Path variable는 뷰클래스 함수에서 self, request 외에 별도의 인자를 가지게 되고, 그 인자값이 엔드포인트가 된다. 따라서 path variable은 인자값이 확실하게 부여가 되는 경우(특정 상품의 정보 등)에 주로 사용되며, urls파일에 반드시 반영을 해 줘야 된다.

테스트를 할 때는 간단하게 url에 해당되는 path variable을 추가해 주면 된다. httpie에서는 http -v url/product/4로 하면 된다.

profile
안녕하세요!

3개의 댓글

comment-user-thumbnail
2021년 4월 27일

좋은 글 감사합니다 :)

답글 달기
comment-user-thumbnail
2021년 8월 5일

잘보고 갑니다! 감사합니다!

답글 달기
comment-user-thumbnail
2022년 1월 14일

좋은글 감사합니다!

답글 달기