HTTP GET 쿼리 문자열 길이 제한을 처리하고 여전히 RESTful을 원합니까?


84

http://www.boutell.com/newfaq/misc/urllength.html에 명시된 바와 같이 HTTP 쿼리 문자열의 길이는 제한되어 있습니다. 클라이언트 (Firefox, IE, ...), 서버 (Apache, IIS, ...) 또는 네트워크 장비 (적용 방화벽, ...)에 의해 제한 될 수 있습니다.

오늘 저는 검색 양식으로이 문제에 직면합니다. 많은 필드가 포함 된 검색 양식을 개발했으며이 양식은 GET 요청으로 서버에 전송되므로 결과 페이지를 북마크 할 수 있습니다.

쿼리 문자열의 길이가 1100 바이트 인 필드가 너무 많고 1024 바이트가 넘는 HTTP GET 요청을 삭제하는 방화벽이 있습니다. 시스템 관리자는 제한이 없도록 대신 POST를 사용하도록 권장합니다.

물론 POST는 작동하지만 검색은 POST가 아닌 GET으로 느껴집니다. 따라서 쿼리 문자열이 너무 길지 않은지 확인하기 위해 필드 이름을 검토하고, 그렇게 할 수 없으면 실용적으로 POST를 사용할 것입니다.

그러나 RESTful 서비스 설계에 결함이 있습니까? GET 요청의 길이가 제한되어 있다면 어떻게 큰 객체를 RESTful 웹 서비스로 보낼 수 있습니까? 예를 들어, 파일을 기반으로 계산하는 프로그램이 있고 다음과 같은 RESTful 웹 서비스를 제공하려는 경우 : http://compute.com?content=<base64 file>. 쿼리 문자열의 길이에 제한이 없기 때문에 작동하지 않습니다.

조금 당황 스럽네요 ...


2
당신의 맥락에서 휴식은 무엇을 의미합니까? 또는 의역 : 왜 GET은 편안하고 POST는 그렇지 않습니까? GET은 간단한 문자열 연결을 사용하여 구성 할 수 있기 때문에? 쿼리 길이 제한은 빠르게 작동하도록 의도 된 앱에서 동적 메모리 할당을 방지하는 것입니다.
khachik 2010

5
검색을하고 싶을 때 무언가를 생성, 삭제 또는 업데이트하고 싶지 않고 데이터를 검색하고 싶기 때문에 POST, DELETE 또는 PUT을 사용해서는 안되며 GET을 사용해야합니다. 이것이 내가 REST를 이해 한 방법이지만 오해 할 수도 있습니다
cbliard

시간이 지남에 따라 검색 결과가 변경 될 수 있으므로 GET은 검색에 적합하지 않습니다. 웹 인프라는 종종 GET 요청의 캐싱을 허용합니다. GET을 사용하면 검색에 대한 오래된 결과를 얻을 위험이 있습니다. POST는 아래에서 권장하는 방법입니다.
occulus

15
모든 것이 시간이 지남에 따라 변경됩니다 ( en.wikipedia.org/wiki/Impermanence ), 이것이 우주의 특성입니다 ... 그러나 "검색 작업"이 결과를 변경하지 않기 때문에 GET을 검색에 사용해야합니다.
Luxspes

답변:


51

설명에 따라 IMHO는 POST를 사용해야합니다. POST는 서버에 데이터를 저장하고 경우에 따라 답변을 얻기위한 것입니다. 귀하의 경우 검색을 수행하고 (서버에 쿼리 보내기) 해당 검색 결과를 가져옵니다 (쿼리 결과 검색).

GET의 정의는 이미 존재하는 자원을 검색하는 데 사용되어야한다고 말합니다. 정의에 따라 POST는 새 리소스를 만드는 것입니다. 이것이 바로 당신이하고있는 일입니다. 서버에 리소스를 생성하고 검색하는 것입니다! 검색 결과를 저장하지 않더라도 서버에 개체를 만들어 검색했습니다. PeterMmm이 미리 말했듯이 POST (쿼리 결과 생성 및 저장)를 사용하여이를 수행 한 다음 GET을 사용하여 쿼리를 검색 할 수 있지만 POST 만 수행하고 결과를 검색하는 것이 더 실용적입니다.

도움이 되었기를 바랍니다! :)


2
당신 말이 맞아요, 검색이 휘발성 새로 계산 된 리소스이기 때문에 POST로 볼 수 있습니다. 하지만 여전히 POST와 GET 사이의 경계를 보는 데 문제가 있습니다. 도서관에있는 모든 공상 과학 책을 검색하고 싶다면 기존 자료를 모아서 GET을 사용하고 싶지만 검색 자체가 새로운 자료이기 때문에 POST로 볼 것을 제안합니다. 따라서 GET의 쿼리 문자열은 데이터 표현을 변경하는 데만 사용해야하며 데이터를 필터링하는 데 사용해야합니다. 내가 맞아?
cbliard

8
POST는 검색을 위해 사용해서는 안됩니다, GET이 당신이 공유 할 수있는 방법 및 캐시, 결과 URL과 결과를 사용해야하는지, 당신은 인터넷의 편안하고 아키텍처를 더 잘 활용할
Luxspes

37
이 대답은 단어를 가지고 노는 것과 비슷합니다. 이 논리에 따라 모든 것을 POST 요청으로 만들 수 있으며 여전히 RESTful이 될 수 있습니다.
supertonsky 2014-07-30

9
이 대답은 어떤 변호사가 저에게 말하는 것 같습니다. :-) 질문은 정말 "저는 GET 케이스가 있습니다.하지만 제 쿼리 문자열이 허용 된 길이를 초과합니다. 어떻게 처리합니까?"입니다. 이 답변을 반대합니다.
G. Stoynev

2
그 논리가 뒤 따르면 모든 요청은 리소스를 생성하고 검색합니다.
Alex

66

HTTP 사양은 실제로 계산을 위해 데이터를 리소스보낼 때 POST를 사용하도록 권장합니다 .

검색은 리소스 자체가 아니라 계산처럼 보입니다. 검색 결과가 리소스가되기를 원한다면 할 수있는 일은 특정 검색 결과를 식별하는 토큰을 만들고 사용자 에이전트를 해당 리소스로 리디렉션하는 것입니다.

그런 다음 일정 시간 후에 검색 결과 토큰을 삭제할 수 있습니다.

POST /search
query=something&category=c1&category=c2&...

201 Created
Location: /search/01543164876

그때

GET /search/01543164876

200 Ok
... your results here...

이렇게하면 브라우저와 프록시가 검색 결과를 계속 캐시 할 수 있지만 POST를 사용하여 쿼리 매개 변수를 제출합니다.

편집하다

명확히하기 위해 01543164876여기는 검색을 나타내는 리소스의 고유 ID를 나타냅니다. 이 두 가지 요청은 기본적으로 이러한 기준으로 새 검색 개체를 만든 다음 생성 된 검색 개체와 관련된 결과를 검색합니다.

이 ID는 각각의 새 요청에 대해 생성 된 고유 ID 일 수 있습니다. 이는 서버가 "검색"개체를 유출하고 캐싱 전략을 사용하여 정기적으로 정리해야 함을 의미합니다.

또는 사용자가 요청한 검색을 실제로 나타내는 모든 검색 기준의 해시 일 수 있습니다. 이렇게하면 검색을 다시 만들면 이미 캐시 된 (또는 그렇지 않을 수있는) 기존 ID가 반환되므로 ID를 재사용 할 수 있습니다.


이것은 쿼리 북마크에 대한 OP 요구 사항을 어떻게 해결합니까?
Rhubarb

2
@Rhubarb는 주어진 검색에 대한 리소스를 생성하여 명확하게 해결합니다.
maulik13 2014

3
결과가 느려집니다. 게시를 수행 한 다음 GET을 수행합니다. 검색을 가져 오기 위해 최소한 300ms 이상을 추가합니다.
jaxxbo

소스 링크가 죽었
Emobe

혼란 스럽습니다. POST와 GET 사이에서 서버는 무엇을합니까? 검색 데이터를 서버에 캐시하고 GET 요청이 들어올 때까지 기다리나요? 그렇게하려면 고유 한 ID를 사용해야하므로 캐시를 검색 할 수 있습니다. 귀하의 답변은 훌륭하지만 완전하지는 않습니다. 그리고 캐시를 사용하면 상태 비 저장이 줄어 듭니다.
Alexander Mills

5

REST는 프로토콜이 아니라 작업을 수행하는 방식입니다. 실제로 GET 일 때 POST를 싫어하더라도 작동합니다.

쿼리를 POST하는 것보다 GET, POST 등의 "표준"정의를 유지해야하는 경우 해당 쿼리는 쿼리 ID로 서버에 저장되고 나중에 GET by id로 쿼리를 요청합니다.


4

귀하의 예와 관련하여 : http://compute.com?content={base64file}, 계산할 "무언가"를 업로드하기 때문에 POST를 사용합니다. 나에게이 "무언가"는 단순한 매개 변수로서의 리소스처럼 느껴집니다.

일반적인 검색에서 이와 달리 GET 및 매개 변수를 사용하기 시작합니다. API 클라이언트가 API를 훨씬 쉽게 테스트하고 사용할 수 있습니다. 읽기 전용 액세스 (대부분의 경우 대부분의 트래픽)를 가능한 간단하게 만드십시오!

그러나 큰 쿼리 문자열의 딜레마는 GET의 유효한 제한입니다. 이 제한에 도달하지 않는 한 GET 및 url-params와 함께 사용하면 실용적으로 갈 것입니다. 이는 검색 사례의 98 %에서 작동합니다. 이 제한에 도달 한 경우에만 작동 한 다음 페이로드 (mime-type 사용 Content-Type: application/x-www-form-urlencoded) 와 함께 POST를 도입하십시오 .

실제 사례가 더 있습니까?


계산은 실제 사례였습니다. 검색에 대해 여러 판매 포인트에서 거래를 검색 할 수 있기를 원하므로 새 브라우저 창을 열어 판매 포인트를 선택합니다. 그리고 유효성을 검사 할 때 검색 양식에서 숨겨진 매개 변수를 수정하여 선택한 판매 포인트를 설정합니다. 정말 많은 경우 결과 검색 요청에 매우 긴 쿼리 문자열이 있습니다.
cbliard

4

GET에 대한 혼란은 브라우저 제한입니다. A2A 또는 P2P 애플리케이션을위한 RESTful 인터페이스를 생성하는 경우 GET 길이에 제한이 없습니다.

이제 브라우저를 사용하여 RESTful 인터페이스 (일명 개발 / 디버깅 중)를 보려면이 제한에 도달하게되지만이를 해결할 수있는 도구가 있습니다.


6
"GET은 브라우저 제한입니다."-서버 제한이기도합니다. 모든 웹 서버가 제한을 적용하고 CDN이있는 경우 제한을 적용 할 수도 있습니다. 다른 도구를 사용하여 요청을 수행한다고해서 서버 제한이 우회되지는 않습니다.
Courtney Miles

0

이것은 쉬운 일입니다. POST를 사용하십시오. HTTP는 GET의 URL 길이에 제한을 두지 않지만 서버는 제한합니다. 실용적으로 행동하고 POST로 해결하십시오.

GET 본문 (허용됨)을 사용할 수도 있지만 올바른 사용법이 아니며 아마도 서버 문제가 발생할 수 있다는 점에서 이중 문제입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.