Programing

REST 웹 애플리케이션의 페이지 매김

lottogame 2020. 3. 6. 08:16
반응형

REST 웹 애플리케이션의 페이지 매김


이것은 이 질문에 대한 보다 일반적인 재구성입니다 (Rails 특정 부분을 제거함).

RESTful 웹 응용 프로그램의 리소스에서 페이지 매김을 구현하는 방법을 잘 모르겠습니다. 내가이라는 리소스를 가지고 있다고 가정하면 products다음 중 어떤 것이 가장 좋은 방법이라고 생각합니까?

1. 쿼리 문자열 만 사용

예. http://application/products?page=2&sort_by=date&sort_how=asc
여기서 문제는 전체 페이지 캐싱을 사용할 수 없으며 URL이 매우 깨끗하고 기억하기 쉽지 않다는 것입니다.

2. 정렬을 위해 페이지를 리소스 및 쿼리 문자열로 사용

예. http://application/products/page/2?sort_by=date&sort_how=asc
이 경우에 볼 수있는 문제는 http://application/products/pages/1사용 sort_by=price하면 완전히 다른 결과를 얻을 수 있고 여전히 페이지 캐싱을 사용할 수 없기 때문에 고유 한 리소스 가 아니라는 것입니다.

3. 페이지를 리소스로 사용하고 정렬을위한 URL 세그먼트

예. http://application/products/by-date/page/2
나는 개인적 으로이 방법을 사용하는 데 아무런 문제가 없지만 누군가는 이것이 좋은 방법이 아니라고 경고했습니다 (그는 이유를주지 않았 으므로 권장하지 않는 이유 를 알고 있다면 알려주십시오)

모든 제안, 의견, 비평은 환영 이상입니다. 감사.


버전 3의 문제는 더 "관점"문제라고 생각합니다. 페이지를 페이지의 리소스 또는 제품으로 보십니까?

페이지를 리소스로 볼 경우 페이지 2에 대한 쿼리는 항상 페이지 2를 생성하므로 완벽하게 훌륭한 솔루션입니다.

그러나 페이지의 제품을 리소스로 볼 경우 2 페이지의 제품이 변경 될 수있는 문제 (오래된 제품이 삭제되거나 기타)가 발생하는 경우 URI가 항상 동일한 리소스를 반환하지는 않습니다.

예를 들어, 고객이 제품 목록 페이지 X에 대한 링크를 저장하고 다음에 링크를 열면 해당 제품이 더 이상 X 페이지에 없을 수 있습니다.


Fionn에 동의하지만 한 단계 더 나아가 페이지가 리소스 아니라 요청의 속성 이라고 말합니다 . 옵션 1 쿼리 문자열 만 선택했습니다. 기분이 좋아. Twitter API 가 편안하게 구성되는 방식이 정말 좋습니다. 너무 간단하지도 않고 복잡하지도 않고 문서화되어 있습니다. 더 좋든 나쁘 든 내가 어떤 방식 으로든 다른 방식으로 무언가를 할 때 울타리에있을 때 "가는"디자인입니다.


HTTP에는 페이지 매김에 적합한 Range 헤더가 있습니다. 보낼 수 있습니다

Range: pages=1

첫 페이지 만 갖습니다. 페이지가 무엇인지 다시 생각해야 할 수도 있습니다. 클라이언트가 다른 범위의 항목을 원할 수도 있습니다. 범위 헤더는 주문을 선언하기 위해 작동합니다.

Range: products-by-date=2009_03_27-

해당 날짜보다 최신의 모든 제품을 얻거나

Range: products-by-date=0-2009_11_30

해당 날짜보다 오래된 모든 제품을 가져옵니다. '0'은 아마도 최상의 솔루션은 아니지만 RFC는 범위 시작을 위해 무언가를 원하는 것 같습니다. units = -range_end를 구문 분석하지 않는 HTTP 구문 분석기가 배치되었을 수 있습니다.

헤더가 (허용 가능한) 옵션이 아닌 경우 첫 번째 솔루션 (모두 쿼리 문자열)은 페이지를 처리하는 방법입니다. 그러나 쿼리 문자열 (알파벳 순서로 정렬 (키 = 값) 쌍)을 정규화하십시오. "? a = 1 & b = x"및 "? b = x & a = 1"미분 문제를 해결합니다.


옵션 1은 응용 프로그램에서 페이지 매김을 동일한 리소스의 다른보기를 생성하는 기술로 보는 범위에서 가장 좋습니다.

그러나 URL 체계는 상대적으로 중요하지 않습니다. 애플리케이션을 하이퍼 텍스트 중심 으로 디자인하는 경우 (모든 REST 애플리케이션은 정의에 따라야 함) 클라이언트는 자체적으로 URI를 구성하지 않습니다. 대신 응용 프로그램에서 클라이언트에 대한 링크를 제공하고 클라이언트가 해당 링크를 따릅니다.

고객이 제공 할 수있는 링크 중 하나는 페이지 매김 링크입니다.

이 모든 것의 유쾌한 부작용은 페이지 매김 URI 구조에 대한 생각을 바꾸고 다음 주에 완전히 다른 것을 구현하더라도 클라이언트가 수정없이 계속 일할 수 있다는 것입니다.


나는 항상 옵션 1의 스타일을 사용했다. 캐싱은 필자의 경우 데이터가 자주 바뀌기 때문에 문제가되지 않았다. 페이지 크기를 구성 할 수 있으면 데이터를 다시 캐시 할 수 없습니다.

기억하기 어렵거나 부정한 URL을 찾지 못했습니다. 나에게 이것은 쿼리 매개 변수를 잘 사용합니다. 리소스는 분명히 제품 목록이며 쿼리 매개 변수는 목록을 표시하는 방법-정렬 및 페이지를 알려줍니다.


옵션 3에 특정 순서로 매개 변수가 있다고 아무도 지적하지 않았습니다. http // application / products / 날짜 / 내림차순 / 이름 / 오름차순 / 페이지 / 2http // application / products / 이름 / 오름차순 / 날짜 / 내림차순 / 페이지 / 2

동일한 리소스를 가리키고 있지만 URL이 완전히 다릅니다.

나를 위해 옵션 1은 "내가 원하는 것"" 내가 원하는 것"을 명확하게 분리하기 때문에 가장 수용 가능한 것 같습니다 (물론 그들 사이에 물음표가 있습니다). 전체 페이지 캐싱은 전체 URL을 사용하여 구현할 수 있습니다 (어쨌든 모든 옵션에서 동일한 문제가 발생 함).

URL에서 매개 변수 접근 방식을 사용하면 유일한 장점은 깨끗한 URL입니다. 매개 변수를 인코딩하고 무손실로 디코딩하는 방법을 찾아야합니다. 물론 URLencode / decode로 갈 수는 있지만 URL을 다시 못생긴 것입니다 :)


쿼리 매개 변수 오프셋 및 제한을 사용하고 싶습니다.

오프셋 : 컬렉션의 항목 인덱스

한도 : 품목 수.

클라이언트는 다음과 같이 오프셋을 계속 업데이트 할 수 있습니다.

offset = offset + limit

다음 페이지를 위해.

경로는 리소스 식별자로 간주됩니다. 그리고 페이지는 리소스가 아니라 리소스 모음의 하위 집합입니다. 페이지 매김은 일반적으로 GET 요청이므로 쿼리 매개 변수는 헤더가 아닌 페이지 매김에 가장 적합합니다.

metamug 사용 합니다 . 그들은 이것을 구성 할 수 있습니다. 선택 쿼리 메타 머그의 페이지 매김


현재 ASP.NET MVC 앱에서 이와 비슷한 구성표를 사용하고 있습니다.

예 : http://application/products/by-date/page/2

구체적으로 : http://application/products/Date/Ascending/3

그러나 나는 이런 식으로 경로에 페이징 및 정렬 정보를 포함시키는 것에 정말로 만족하지 않습니다.

항목 목록 (이 경우 제품)은 변경 가능합니다. 즉, 다음에 누군가 페이징 및 정렬 매개 변수가 포함 된 URL로 돌아 오면 결과가 변경되었을 수 있습니다. 따라서 http://application/products/Date/Ascending/3정의되지 않은 변경되지 않는 제품 세트를 가리키는 고유 URL 이라는 아이디어 가 사라집니다.


이 사이트를 방문한 모범 사례를 찾고 있습니다.

http://www.restapitutorial.com

리소스 페이지에는 저자가 제안한 전체 REST 모범 사례가 포함 된 .pdf를 다운로드 할 수있는 링크가 있습니다. 무엇보다도 페이지 매김에 대한 섹션이 있습니다.

필자는 Range 헤더와 query-string 매개 변수를 모두 사용하여 지원을 추가 할 것을 제안합니다.

의뢰

HTTP 헤더 예 :

Range: items=0-24

쿼리 문자열 매개 변수 예 :

GET http://api.example.com/resources?offset=0&limit=25

여기서 offset 은 시작 항목 번호이고 limit 은 반환 할 최대 항목 수입니다.

응답

응답에는 반환되는 항목 수와 아직 검색되지 않은 총 항목 수를 나타내는 Content-Range 헤더가 포함되어야합니다.

HTTP 헤더 예 :

Content-Range: items 0-24/66

Content-Range: items 40-65/*

.pdf에는 더 구체적인 경우에 대한 다른 제안이 있습니다.


"page"가 실제로 리소스가 아니라는 것을 slf에 동의하는 경향이 있습니다. 반면에 옵션 3은 더 깨끗하고 읽기 쉽고 사용자가 더 쉽게 추측 할 수 있으며 필요한 경우 입력 할 수도 있습니다. 옵션 1과 3 사이를 찢었지만 옵션 3을 사용하지 않는 이유는 없습니다.

또한 멋지게 보이지만 쿼리 문자열이나 URL 세그먼트 대신 숨겨진 매개 변수를 사용하는 한 가지 단점은 사용자가 특정 페이지에 책갈피를 지정하거나 직접 연결할 수 없다는 것입니다. 응용 프로그램에 따라 문제가 될 수도 있고 아닐 수도 있지만 알고 있어야 할 것이 있습니다.


전에 솔루션 3을 사용했습니다 (많은 장고 앱을 작성합니다). 그리고 나는 그것에 문제가 있다고 생각하지 않습니다. 다른 두 개와 마찬가지로 생성 가능하며 (대량 긁기 등을 해야하는 경우) 깨끗해 보입니다. 또한 사용자는 URL (공개 앱인 경우)을 추측 할 수 있으며 사람들은 원하는 곳으로 바로 이동할 수 있고 URL 추측은 힘을 실어줍니다.


내 프로젝트에서 다음 URL을 사용합니다.

http://application/products?page=2&sort=+field1-field2

이것은 "field1에서 오름차순으로 정렬 한 다음 field2로 내림차순으로 정렬 된 두 번째 페이지를 페이지에 제공"한다는 의미입니다. 또는 더 많은 유연성이 필요한 경우 다음을 사용합니다.

http://application/products?skip=20&limit=20&sort=+field1-field2

참고 URL : https://stackoverflow.com/questions/776448/pagination-in-a-rest-web-application



반응형