[rest] 요청 본문이있는 HTTP GET

우리 응용 프로그램을 위해 새로운 RESTful 웹 서비스를 개발 중입니다.

특정 엔티티에서 GET을 수행 할 때 클라이언트는 엔티티의 컨텐츠를 요청할 수 있습니다. 목록 정렬과 같은 일부 매개 변수를 추가하려는 경우 쿼리 문자열에 이러한 매개 변수를 추가 할 수 있습니다.

또는 사람들이 요청 본문에서 이러한 매개 변수를 지정할 수 있기를 바랍니다.
HTTP / 1.1 은 이것을 명시 적으로 금지하지 않는 것 같습니다. 이를 통해 더 많은 정보를 지정할 수 있으며 복잡한 XML 요청을보다 쉽게 ​​지정할 수 있습니다.

내 질문 :

  • 이것이 좋은 생각입니까?
  • HTTP 클라이언트는 GET 요청 내에서 요청 본문 사용에 문제가 있습니까?

http://tools.ietf.org/html/rfc2616



답변

GET 요청에 바디를 포함시키는 것에 대한 Roy Fielding의 의견 .

예. 다시 말해, 모든 HTTP 요청 메시지는 메시지 본문을 포함 할 수 있으므로이를 염두에두고 메시지를 구문 분석해야합니다. 그러나 GET에 대한 서버 시맨틱은 본문에 요청에 대한 시맨틱 의미가 없도록 제한됩니다. 구문 분석에 대한 요구 사항은 메소드 시맨틱에 대한 요구 사항과 별개입니다.

따라서 그렇습니다. GET을 사용하여 본문을 보낼 수 있으며, 그렇게하는 것은 결코 유용하지 않습니다.

이것은 사양이 분할되면 (작업 진행 중) 다시 명확 해 지도록 HTTP / 1.1의 계층화 된 디자인의 일부입니다.

…. 로이

예, GET을 사용하여 요청 본문을 보낼 수 있지만 의미가 없습니다. 서버에서 구문 분석 하고 내용에 따라 응답을 변경하여 의미를 부여 하면 HTTP / 1.1 스펙 4.3 절 에서이 권장 사항을 무시하는 것입니다 .

[…] 요청 방법 엔티티 바디에 대해 정의 된 의미를 포함하지 않는 경우, 메시지 본문 SHOULD 요청을 처리 할 때 무시된다.

HTTP / 1.1 스펙 섹션 9.3 에서 GET 메소드에 대한 설명은 다음과 같습니다.

GET 메소드는 Request-URI로 식별 된 모든 정보 ([…])를 검색하는 것을 의미합니다.

이것은 요청 본문이 GET 요청에서 자원 식별의 일부가 아니라 요청 URI만을 나타냅니다.

업데이트
“HTTP / 1.1 사양”으로 참조 된 RFC2616은 이제 더 이상 사용되지 않습니다. 2014 년에는 RFC 7230-7237로 대체되었습니다. “요청을 처리 할 때 메시지 본문을 무시해야합니다”라는 인용문이 삭제되었습니다. “메시지 본문에 대한 용도를 정의하지 않더라도 요청 메시지 프레임은 메소드 시맨틱과 무관합니다.” 삭제되었습니다. -댓글에서


답변

HTTP 사양에서 명시 적으로 배제하지 않는 한 그렇게 할 는 있지만 사람들이 그런 식으로 작동하지 않기 때문에 단순히 피하는 것이 좋습니다. HTTP 요청 체인에는 여러 단계가 있으며, HTTP 요청 체인은 “대부분”HTTP 사양을 준수하지만, 웹 브라우저에서 전통적으로 사용되는 것처럼 동작한다는 것뿐입니다. (투명한 프록시, 가속기, A / V 툴킷 등을 생각하고 있습니다.)

이것은 견고성 원칙의 배후에있는 대략적인 것입니다. “당신이 받아들이는 것에서 자유롭고, 당신이 보내는 것에서 보수적이어야합니다.”

그러나 그럴만한 이유가 있다면 그렇게하십시오.


답변

캐싱을 활용하려고하면 문제가 발생할 수 있습니다. 프록시는 매개 변수가 응답에 영향을 미치는지 확인하기 위해 GET 본문을 보지 않습니다.


답변

어느 위해 RESTClient 이나 REST 콘솔은 이 기능을 지원하지만 컬을 수행합니다.

HTTP 사양은 4.3 절에 말한다

요청 방법 (5.1.1 절)의 명세가 엔티티 본문을 요청으로 전송하는 것을 허용하지 않는다면, 메시지 본문은 요청에 포함되어서는 안된다 (MUST NOT).

섹션 5.1.1 은 다양한 방법에 대해 섹션 9.x로 리디렉션합니다. 이들 중 어느 것도 메시지 본문의 포함을 명시 적으로 금지하지 않습니다. 하나…

섹션 5.2에 따르면

인터넷 요청으로 식별 된 정확한 리소스는 Request-URI와 Host header 필드를 모두 검사하여 결정됩니다.

9.3 절은 말한다

GET 메소드는 Request-URI에 의해 식별되는 모든 정보 (엔터티 형태)를 검색하는 것을 의미합니다.

GET 요청을 처리 할 때 서버는 Request-URI 및 Host 헤더 필드 이외의 다른 것을 검사 할 필요 가 없음을 함께 제안 합니다.

요약하면 HTTP 사양은 GET을 사용하여 메시지 본문을 보내지 못하게하지는 않지만 모든 서버에서 지원하지 않는 경우 놀라지 않을 정도로 모호합니다.


답변

Elasticsearch는 본문이있는 GET 요청을 수락합니다. 이것이 바람직한 방법 인 것 같습니다. Elasticsearch 안내서

Ruby 드라이버와 같은 일부 클라이언트 라이브러리는 개발 모드에서 cry 명령을 stdout에 기록 할 수 있으며이 구문을 광범위하게 사용합니다.


답변

달성하려는 것은 훨씬 일반적인 방법과 GET과 함께 페이로드를 사용하지 않는 방법으로 오랫동안 수행되었습니다.

특정 검색 미디어 유형을 구축하거나 더 RESTful하고 싶다면 OpenSearch와 같은 것을 사용하고 서버가 지시 한 URI에 요청을 POST하십시오 (예 : / search). 그런 다음 서버는 검색 결과를 생성하거나 최종 URI를 빌드하고 303을 사용하여 리디렉션 할 수 있습니다.

이것은 전통적인 PRG 방법을 따르는 장점이 있으며 캐시 중개인이 결과를 캐시하는 데 도움이됩니다.

즉, URI는 ASCII가 아닌 모든 항목에 대해 인코딩되므로 application / x-www-form-urlencoded 및 multipart / form-data입니다. ReSTful 시나리오를 지원하려는 경우 또 다른 사용자 정의 json 형식을 작성하는 대신 이것을 사용하는 것이 좋습니다.


답변

몸과 함께 GET을 보내거나 POST를 보내고 RESTish religiosity를 포기할 수 있습니다.

훌륭한 결정도 아니지만 GET 본문을 전송하면 일부 클라이언트 및 일부 서버의 문제를 방지 할 수 있습니다.

POST를 수행하면 일부 RESTish 프레임 워크에 장애물이있을 수 있습니다.

Julian Reschke는 위의 “SEARCH”와 같은 비표준 HTTP 헤더를 사용하여 제안했을 때 지원할 가능성이 적다는 점을 제외하고는 훌륭한 해결책이 될 수 있다고 제안했습니다.

위의 각 작업을 수행 할 수 있고 수행 할 수없는 클라이언트를 나열하는 것이 가장 생산적 일 수 있습니다.

본문과 함께 GET을 보낼 수없는 고객 (내가 아는 것) :

  • XmlHTTPRequest 피들러

본문과 함께 GET을 보낼 수있는 클라이언트 :

  • 대부분의 브라우저

GET에서 본문을 검색 할 수있는 서버 및 라이브러리 :

  • 아파치
  • PHP

GET에서 본문을 제거하는 서버 (및 프록시) :

  • ?