API 문서 작성 일지: (2) 쿼리

박정환·2022년 8월 18일

이제 메인 페이지에 대한 API 문서를 작성해보자.

  1. 먼저 메인페이지를 구성하는데 필요한 데이터를 생각해보자.
  • 추천 컬렉션:

유저가 '카테고리'를 클릭하면 해당 카테고리에 속하는 컬렉션을 클라이언트단에 보내야 한다.
request: 카테고리('string') --> response: collection(title, name, likes, id)

해당 타이틀을 클릭하면 컬렉션 디테일 페이지로 넘어가야 한다. (collection/{collection_id})

"과학" 카테고리를 클릭하면 어떤 요청을 보내야 하지?

처음에 static으로 심어 놓으면, 일부 HTML 구조가 바뀔 수 있다. HTML 내부에서 반복문을 돌릴 수 있도록 하기도 해서 일부 코드가 삭제될 수도 있다. api로 받은 데이터를 심는데 상관이 없나?

BASE_URL/ --> 서버를 렌더링해주는 함수

메인페이지에 띄워지는 추천 컬렉션을 위한 데이터를 보내주는 함수를 보내기 위해선 어떤 URI 로 접근하게 해야 하나.

BASE_URL/collection/과학

  • 추천 인사이트

시간의 한계상 이건 그냥 static으로 박아도 될 것 같다. 괜찮은 더미 데이터 3개만 박아 놓자.

  • 오늘의 인사이트

처음 페이지 렌더할 때 5개 카테고리 중에서 하나를 일단 보여준다.

request:

GET post/{category_name}/today

  1. 고려해야 하는 부분: 나중에 다른 페이지에서 포스트를 요청하는 맥락이 있을 때, 이 uri가 최선이 아닐 수 있지 않을까.

  2. 자원의 종류-post-가 정해지면, 그 안에서 category나, 날짜 필터 등을 원한다면 그건 get 요청 안의 데이터로 정할 수 있을 거 같다.

--> 이 방식은 REST 원칙을 어기는 것이라고 한다(https://stackoverflow.com/questions/5020704/how-to-design-restful-search-filtering)

  1. 하지만 'post/' 라면, 이는 통상적으로 post 목록에 대한 페이지가 된다. 물론 이후 rest api로 한다면, 계속 이와 같이 처리할 수 있긴하다. 아직 post 전체 목록 페이지는 없으므로.

그럼 request는 다음과 같이 규정하자.

GET /post
{
cateogory: '정치'

}

최근 7일을 어떻게 표현할까.

  1. rest api 에 필터링과 쿼리 개념이 있다. url 주소 뒤에 '?index=3'와 같은 것을 본 적이 있다.
    post 자원에 접근하기 위한 url은 /post 이면 충분한 것이고, 그 뒤에 쿼리를 붙이면 된다. 이를 url parameter라고 한다.

https://www.moesif.com/blog/technical/api-design/REST-API-Design-Filtering-Sorting-and-Pagination/

GET /items?state=active&seller_id=1234

4.1

range 매칭도 가능하다.

URL parameter는 3개의 요소로 이루어져 있다.

  • 필드의 이름
  • 비교 연산자(eq, lte, gte)
  • 필터 값

비교연산자를 [] 괄호에 넣음으로써 인코딩하는 방법이 있다.

GET /items?price[gte]=1-&price[lte]=100

비교연산자에는 [lte], [gte] 도 있지만 [exists], [before], [after] 과 같은 것도 있을 수 있다.

자, 그럼 클라이언트는 url 뒤에 어떻게 이런 쿼리를 붙여서 보내고, 백엔드는 이를 어떻게 받아서 처리할까.
url에 담아서 보낸다면, 백엔드는 이를 어떻게 읽을 수 있지? 내가 배운 바 안에서 url 을 읽는 방법은 없었다.

4.2

페이지네이션: 대부분의 엔드포인트는 개체의 리스트를 보내서 페이지네이션이 필요하다.
페이지네이션이 없으면 수백만 개의 히트가 발생하여 많은 네트워크 트래픽의 발생을 요한다.

// 페이지네이션은 클라이언트 단에서 순차적으로 보게 하는 거 아닌가? 페이지 단위로 데이터를 보낸다는 뜻인가?

GET /items?limit=20&&offset=100
100번째 row부터 20개의 row를 반환한다는 뜻이다.

GET /post/?recommended[asc]&&limit=20

sorting도 된다.

GET /users?sort_by=asc(email)

or

GET /users?sort_by=desc(email)

4.3
api 디자인 방법은 잘 알았다. 그래서 어떻게 이를 구현하는데?

GET /items?q=haha

일 때 이렇게 파싱할 수 있다.

request.GET.get('q', '')

url에 정규표현식을 쓸 수도 있다.

(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),

이런 대안도 있다.

urlpatterns = [path('items/<str:queryparams>', views.get)]
list2 = queryparams.split('&')

collection/2/likes

  1. 이제 테스트해보자.
1. 포스트 인스턴스 생성하기 
2. post/?sort_by=asc(recommended_id)&category=정치

param = [sort_by=asc(recommendeD_id, category=정치]

of 

request.GET.get('sort_by', 



3. 이를 바탕으로 어떻게 쿼리할지 생각해보기. 



4. 

쿼리셋을 어떻게 JsonResponse에 담아서 보낼 수 있을까. 어
  1. 뭐가 더 바람직한 REST API URL 컨벤션일까.

3번 유저가 작성한 모든 article을 get 한다.

/user/3/article
/article?user_id=3/

오늘의 인사이트이니까, 그중에서

먼저 베이스URL 로 GET 요청을 보낼 때(브라우저로 타이핑해서 들어오는 케이스),

이때 Get 요청의 데이터에는 아무것도 안들어오는 것으로 인식해야 하나?

0개의 댓글