2012-08-28 4 views
54

내 RESTful API에서 페이지 매김을 지원하고 싶다.RESTful API에서 페이지 매김 응답 페이로드

내 API 메소드는 /products/index을 통해 제품의 JSON 목록을 반환해야합니다. 그러나 잠재적으로 제품의 수천이 있고, 내 요청이 같은 찾아야한다, 그래서 나는 그들을 통해 페이지에 원하는 :

/products/index?page_number=5&page_size=20 

하지만 내 JSON 응답을 같이 할 필요가 않습니다를? API 소비자는 대개 응답에서 페이지 매김 메타 데이터를 기대합니까? 아니면 필요한 제품 배열 일뿐입니까? 왜?

트위터의 API에 메타 데이터가 포함 된 것처럼 보입니다 : https://dev.twitter.com/docs/api/1/get/lists/members (예 요청 참조).

{ 
    "page_number": 5, 
    "page_size": 20, 
    "total_record_count": 521, 
    "records": [ 
    { 
     "id": 1, 
     "name": "Widget #1" 
    }, 
    { 
     "id": 2, 
     "name": "Widget #2" 
    }, 
    { 
     "id": 3, 
     "name": "Widget #3" 
    } 
    ] 
} 

제품 그냥 배열 (NO 메타 데이터) :

REST 서비스 소비에 대한 몇 가지 라이브러리를 쓴 사람으로
[ 
    { 
    "id": 1, 
    "name": "Widget #1" 
    }, 
    { 
    "id": 2, 
    "name": "Widget #2" 
    }, 
    { 
    "id": 3, 
    "name": "Widget #3" 
    } 
] 

답변

70

ReSTful API는 주로 다른 시스템에서 사용되기 때문에 응답 헤더에 페이징 데이터를 넣습니다. 그러나 일부 API 사용자는 응답 헤더에 직접 액세스하지 못하거나 API를 통해 UX를 구축 할 수 있으므로 JSON 응답의 메타 데이터를 필요할 때 검색 할 수있는 방법을 제공하는 것이 좋습니다.

구현시 요청할 때 기본적으로 컴퓨터가 읽을 수있는 메타 데이터와 사람이 읽을 수있는 메타 데이터가 포함되어야합니다. 사람이 읽을 수있는 메타 데이터는 원하는 경우 모든 요청과 함께 또는 include=metadata 또는 include_metadata=true과 같은 쿼리 매개 변수를 통해 주문형으로 반환 될 수 있습니다.

특정 시나리오에서 레코드와 함께 각 제품의 URI를 포함합니다. 이렇게하면 API 소비자가 개별 제품에 대한 링크를 쉽게 만들 수 있습니다. 또한 페이징 요청의 한계에 따라 합당한 기대치를 설정합니다.페이지 크기에 대한 기본 설정을 구현하고 문서화하는 것은 허용되는 방법입니다. 예를 들어 GitHub's API은 기본 페이지 크기를 최대 30 개의 레코드로 설정하고 더하기 API를 쿼리 할 수있는 횟수에 대한 제한 속도를 설정합니다. API에 기본 페이지 크기가있는 경우 쿼리 문자열은 페이지 인덱스 만 지정할 수 있습니다. /products?page=5&per_page=20&include=metadata로 이동하면 사람이 읽을 수있는 시나리오에서

는 응답이 될 수있다 : 기계 판독 메타 데이터에 대한

{ 
    "_metadata": 
    { 
     "page": 5, 
     "per_page": 20, 
     "page_count": 20, 
     "total_count": 521, 
     "Links": [ 
     {"self": "/products?page=5&per_page=20"}, 
     {"first": "/products?page=0&per_page=20"}, 
     {"previous": "/products?page=4&per_page=20"}, 
     {"next": "/products?page=6&per_page=20"}, 
     {"last": "/products?page=26&per_page=20"}, 
     ] 
    }, 
    "records": [ 
    { 
     "id": 1, 
     "name": "Widget #1", 
     "uri": "/products/1" 
    }, 
    { 
     "id": 2, 
     "name": "Widget #2", 
     "uri": "/products/2" 
    }, 
    { 
     "id": 3, 
     "name": "Widget #3", 
     "uri": "/products/3" 
    } 
    ] 
} 

, 내가 응답에 Link headers를 추가 :

Link: </products?page=5&perPage=20>;rel=self,</products?page=0&perPage=20>;rel=first,</products?page=4&perPage=20>;rel=previous,</products?page=6&perPage=20>;rel=next,</products?page=26&perPage=20>;rel=last 

(링크 헤더 값을 URL 인코딩해야 함)

... 그리고 아마도 사용자 정의,236,347,818,응답 헤더, 그렇게 선택하는 경우 : 링크 헤더 제가 오전하는 페이지 알려으로 인간 중심의 메타 데이터에 공개

total-count: 521 

다른 페이징 데이터, 기계 중심의 메타 데이터에 대한 불필요한 될 수있는 페이지 당 숫자를 표시하고 배열의 레코드 수를 빠르게 검색 할 수 있습니다. 따라서 전체 카운트의 머리글 만 만들 수 있습니다. 나중에 언제든지 마음을 바꿔 더 많은 메타 데이터를 추가 할 수 있습니다.

제쳐두고, URI에서 /index을 삭제했을 수 있습니다. ReST 끝점에서 컬렉션을 노출하도록하는 것이 일반적으로 허용되는 규칙입니다. 끝 부분에 /index을 가볍게 두드리는 것.

다음은 API를 사용하거나 만들 때 가지고있는 몇 가지 예입니다. 희망이 도움이됩니다!

+0

per_page가 page_size –

+1

''page_count ': 20'' 및'{ "last": "/ products? page = 26 & per_page = 20"}'규칙을 따르지 않습니까? –

+0

페이지 1에서 페이지 x까지 모든 레코드를 가져 오는 동안 제품 수가 갑자기 증가한다면 어떻게됩니까? – MeV

23

, 내가 당신에게 줄 수 있도록 메타 데이터와

왜 결과를 메타 데이터로 래핑하는 것이 최선의 방법인지에 대한 고객의 관점 :

  • , 어떻게 클라이언트가 아직 모든 것을 수신하지 못했고 결과 집합을 페이징을 계속해야하는지 알 수 있습니까? 최악의 경우 다음 페이지를 앞서는 시각을 수행하지 않은 UI에서는 더 이상 데이터를 실제로 가져 오지 않은 다음/더보기 링크로 표시 될 수 있습니다.
  • 메타 데이터를 응답에 포함 시키면 클라이언트가 더 적은 상태를 추적 할 수 있습니다. 이제 요청에 요청 상태 (이 경우 데이터 집합에 커서)를 재구성하는 데 필요한 메타 데이터가 응답에 포함되어 있으므로 REST 요청과 응답을 일치시킬 필요가 없습니다.
  • 상태가 응답의 일부인 경우 동일한 데이터 집합에 여러 요청을 동시에 수행 할 수 있으며 요청이 도착한 순서대로 요청을 처리 할 수 ​​있습니다.

그리고 제안 사항 : Twitter API처럼 page_number를 직선 색인/커서로 바꾸어야합니다. 이유는 API가 클라이언트가 요청 당 페이지 크기를 설정할 수 있기 때문입니다. 반환 된 page_number는 클라이언트가 지금까지 요청한 페이지 수 또는 마지막으로 사용한 page_size가 주어진 페이지 수 (거의 확실하지만 나중에 이러한 모호성을 피하지 않는 이유는 무엇입니까?)?

+5

, = 옆에 확인해를 생략 할 수있는 적합한 솔루션이 될 것입니다 다음 페이지가 없다면 링크 하시겠습니까? 두 번째 글 머리 기호에 대한 정보는 클라이언트에 대한 응답에서 계속 사용할 수 있습니다. 응답의 본문에있는 것이 아니라 머리글에 있습니다. 마지막 단락에 +1하십시오. –

5

동일한 헤더를 추가하는 것이 좋습니다. 메타 데이터를 헤더로 이동하면 result, data 또는 records과 같은 봉투를 제거하는 데 도움이되며 응답 본문에는 필요한 데이터 만 포함됩니다. 페이지 매김 링크를 생성하는 경우 Link 헤더를 사용할 수 있습니다. 자신감 파일의 경우

https://github.com/adnan-kamili/rest-api-response-format

: 자세한 내용은

HTTP/1.1 200 
    X-Pagination-Count: 100 
    X-Pagination-Page: 5 
    X-Pagination-Limit: 20 
    Content-Type: application/json 

    [ 
     { 
     "id": 10, 
     "name": "shirt", 
     "color": "red", 
     "price": "$23" 
     }, 
     { 
     "id": 11, 
     "name": "shirt", 
     "color": "blue", 
     "price": "$25" 
     } 
    ] 

는 참조

첫 번째 총알

https://github.com/adnan-kamili/swagger-response-template