[rest] 객체의 총 항목 수를 반환하는 가장 좋은 RESTful 방법은 무엇입니까?

내가 참여하고있는 대규모 소셜 네트워킹 웹 사이트를위한 REST API 서비스를 개발 중입니다. 지금까지는 잘 작동하고 있습니다. 나는 발급 할 수 있습니다 GET, POST, PUTDELETE객체의 URL에 대한 요청과 내 데이터에 영향을 미친다. 그러나이 데이터는 페이징됩니다 (한 번에 30 개의 결과로 제한됨).

그러나 내 API를 통해 총 회원 수를 얻는 가장 좋은 RESTful 방법은 무엇입니까?

현재 다음과 같은 URL 구조에 요청을 발행합니다.

  • / api / members — 구성원 목록을 반환합니다 (위에서 언급 한대로 한 번에 30 개)
  • / api / members / 1 — 사용 된 요청 방법에 따라 단일 멤버에 영향을줍니다.

내 질문은 : 어떻게 비슷한 URL 구조를 사용하여 내 응용 프로그램의 총 멤버 수를 얻습니까? 분명히 id필드 (Facebook의 Graph API와 유사)를 요청 하고 결과를 세는 것은 효과가 없을 것입니다 .30 개의 결과 조각 만 반환됩니다.



답변

/ API / users에 대한 응답이 페이징되고 30 개의 레코드 만 리턴하지만 응답에 총 레코드 수 및 페이지 크기, 페이지 번호 / 오프셋 등과 같은 기타 관련 정보도 포함시키지 못하게하는 것은 없습니다. .

StackOverflow API는 동일한 디자인의 좋은 예입니다. 다음은 Users 메소드에 대한 설명서입니다-https: //api.stackexchange.com/docs/users


답변

이런 종류의 상황 정보에 HTTP 헤더를 사용하는 것이 좋습니다.

총 요소 수에는 X-total-count헤더를 사용 합니다.
다음 페이지, 이전 페이지 등의 링크는 http Link헤더를 사용합니다 :
http://www.w3.org/wiki/LinkHeader

Github은 https://developer.github.com/v3/#pagination 과 같은 방식으로 수행합니다.

내 의견으로는 하이퍼 링크를 지원하지 않는 콘텐츠 (예 : 이진, 그림)를 반환 할 때도 사용할 수 있기 때문에 더 깨끗합니다.


답변

나는 최근에 이것과 다른 REST 페이징 관련 질문에 대한 광범위한 연구를 해 왔으며 여기에 내 발견 사항을 추가하는 것이 건설적인 것이라고 생각했습니다. 나는 페이징에 대한 생각과 그들이 친밀하게 관련된 수를 포함하도록 질문을 조금 확장하고 있습니다.

헤더

페이징 메타 데이터는 응답 헤더 형식으로 응답에 포함됩니다. 이 접근 방식의 가장 큰 장점은 응답 페이로드 자체가 실제 데이터 요청자가 요청한 것입니다. 페이징 정보에 관심이없는 클라이언트의 응답 처리를보다 쉽게 ​​만듭니다.

총 수를 포함하여 페이징 관련 정보를 반환하기 위해 와일드에 사용되는 많은 (표준 및 사용자 정의) 헤더가 있습니다.

X-Total-Count

X-Total-Count: 234

이것은 내가 야생에서 찾은 일부 API 에서 사용됩니다 . 루프백에이 헤더에 대한 지원을 추가하기위한 NPM 패키지 도 있습니다 . 일부 기사 에서는이 헤더를 설정하는 것이 좋습니다.

Link헤더 와 함께 사용되는 경우가 많습니다. 페이징에는 매우 적합한 솔루션이지만 총 개수 정보가 없습니다.

링크

Link: </TheBook/chapter2>;
      rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
      </TheBook/chapter4>;
      rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel

나는 일반적인 합의가 사용하는 것으로,이 주제에 많이 읽고, 느낌이 Link헤더를 사용하여 클라이언트에 대한 링크를 페이징 제공하기 위해 rel=next, rel=previous이에 등의 문제는 인, 얼마나 많은 총 레코드의 정보 부족이다 많은 API가 이것을X-Total-Count 헤더 .

또는 JsonApi 표준 과 같은 일부 API 는 Link형식을 사용 하지만 헤더 대신 응답 엔벨로프에 정보를 추가하십시오. 이는 엔벨로프를 추가하여 실제 데이터 자체에 대한 액세스 복잡성을 증가시키는 대신에 메타 데이터에 대한 액세스를 단순화하고 총 수 정보를 추가 할 수있는 장소를 만듭니다.

컨텐츠 범위

Content-Range: items 0-49/234

Range header 라는 블로그 기사에서 홍보 한 결과, 페이지 매김을 선택합니다. . 저자는 페이지 매김에 RangeContent-Range헤더를 사용하는 강력한 사례를 만듭니다 . 이 헤더 에서 RFC 를 주의 깊게 읽으면 실제로 RFC에서 바이트 범위를 넘어 그 의미를 확장하는 것이 예상되었으며 명시 적으로 허용되는 것을 알 수 있습니다. 의 맥락에서 사용하는 경우 items대신 bytes, 레인지 헤더는 실제로 모두 요청에 우리에게 항목의 특정 범위를 방법을 제공하고 응답 항목과 관련된 전체 결과의 범위는 무엇을 나타냅니다. 이 헤더는 또한 총 수를 표시하는 좋은 방법을 제공합니다. 그리고 일대일로 페이징을 매핑하는 것은 진정한 표준입니다. 또한 야생 에서도 사용됩니다 .

봉투

자주 사용 하는 Q & A 웹 사이트의 API를 포함 하여 많은 API 는 데이터에 대한 메타 정보를 추가하는 데 사용되는 데이터 래퍼 인 envelope를 사용합니다 . 또한 ODataJsonApi 표준은 모두 응답 범위를 사용합니다.

이에 대한 가장 큰 단점은 실제 데이터가 엔벨로프에서 찾아야하므로 응답 데이터 처리가 더 복잡해진다는 것입니다. 또한 해당 봉투에는 여러 가지 형식이 있으므로 올바른 것을 사용해야합니다. OData와 JsonApi의 응답 엔벨로프는 응답의 여러 지점에서 메타 데이터에서 혼합되는 OData와는 크게 다릅니다.

별도의 엔드 포인트

나는 이것이 다른 답변에서 충분히 다루어 졌다고 생각합니다. 여러 유형의 엔드 포인트가 있으므로 혼동된다는 의견에 동의하기 때문에 이것을 많이 조사하지 않았습니다. 모든 엔드 포인트가 (자원 모음)을 나타내는 것이 가장 좋다고 생각합니다.

추가 생각

응답과 관련된 페이징 메타 정보를 전달할 필요가있을뿐만 아니라 클라이언트가 특정 페이지 / 범위를 요청할 수도 있습니다. 일관된 솔루션으로 끝나기 위해이 측면을 보는 것도 흥미 롭습니다. 여기에서도 헤더 ( Range헤더가 매우 적합 함) 또는 쿼리 매개 변수와 같은 다른 메커니즘을 사용할 수 있습니다 . 어떤 사람들은 몇 가지 사용 사례에 의미가 있습니다 별도의 자원 (예를 들어 같은 결과 페이지를 치료 옹호 /books/231/pages/52나는 등 자주 사용하는 요청 매개 변수의 야생 범위를 선택 끝났다. pagesize, page[size]limit등 지원 외에 Range헤더 (요청 매개 변수로 게다가).


답변

실제 품목이 필요하지 않은 경우의 대안

Franci Penov의 답변 은 확실히 가장 좋은 방법이므로 요청되는 엔티티에 대한 모든 추가 메타 데이터와 함께 항상 항목을 반환하십시오. 그렇게해야합니다.

그러나 때때로 모든 데이터를 반환하는 것은 전혀 필요하지 않기 때문에 의미가 없습니다. 요청한 리소스에 대한 메타 데이터 만 있으면됩니다. 총 페이지 수 또는 다른 페이지 수 이 경우 항상 URL 쿼리가 서비스에 항목을 반환하지 말고 메타 데이터 만 반환하도록 지시 할 수 있습니다.

/api/members?metaonly=true
/api/members?includeitems=0

또는 비슷한 …


답변

HEAD 요청에 대한 응답으로 카운트를 사용자 정의 HTTP 헤더로 리턴 할 수 있습니다. 이렇게하면 클라이언트가 개수 만 원하는 경우 실제 목록을 반환 할 필요가 없으며 추가 URL이 필요하지 않습니다.

또는 끝점에서 끝점까지 제어 된 환경에있는 경우 COUNT와 같은 사용자 지정 HTTP 동사를 사용할 수 있습니다.


답변

다음과 같이 헤더를 추가하는 것이 좋습니다.

HTTP/1.1 200

Pagination-Count: 100
Pagination-Page: 5
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/rest-api-response-format

스와 거 파일의 경우 :

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


답변

“X-“-접두사가 사용되지 않습니다. ( https://tools.ietf.org/html/rfc6648 참조 )

“Accept-Ranges”는 페이지 매김 범위를 매핑하는 가장 좋은 방법으로 나타났습니다. https://tools.ietf.org/html/rfc7233#section-2.3
“범위 단위”는 “바이트”또는 ” 토큰”. 둘 다 사용자 정의 데이터 유형을 나타내지 않습니다. ( https://tools.ietf.org/html/rfc7233#section-4.2 참조 ) 그래도 여전히

HTTP / 1.1 구현은 다른 단위를 사용하여 지정된 범위를 무시할 수 있습니다.

사용자 지정 범위 단위를 사용하는 것은 프로토콜에 위배되지 않지만 무시 될 수 있습니다.

이런 식으로 Accept-Ranges를 “members”또는 원하는 범위의 단위 유형으로 설정해야합니다. 또한 Content-Range를 현재 범위로 설정하십시오. ( https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.12 참조 )

어느 쪽이든, 나는 200 대신 206을 보내도록 RFC7233 ( https://tools.ietf.org/html/rfc7233#page-8 )을 권장합니다 .

모든 전제 조건이 참이면, 서버는
대상 자원에 대한 범위 헤더 필드를 지원하고 지정된 범위가
유효하고 만족할 수 있습니다 (2.1 절에 정의 된대로), 서버는
206 (부분 컨텐츠) 응답을 보내야합니다
섹션 4에 정의 된대로 요청
된 만족스러운
범위에 해당 하는 하나 이상의 부분 표현을 포함하는 페이로드

결과적으로 다음과 같은 HTTP 헤더 필드가 생깁니다.

부분 컨텐츠의 경우 :

206 Partial Content
Accept-Ranges: members
Content-Range: members 0-20/100

전체 내용 :

200 OK
Accept-Ranges: members
Content-Range: members 0-20/20