URL 쿼리 매개 변수가 포함 된 HTTP POST-좋은 아이디어입니까? [닫은]


451

HTTP를 통과하는 API를 설계 중이며 HTTP POST 명령을 사용하는지 궁금하지만 URL 쿼리 매개 변수 만 있고 요청 본문이없는 것이 좋은 방법입니다.

고려 사항 :

  • "좋은 웹 디자인"은 POST를 통해 비등 전성 액션을 보내야합니다. 이것은 비등 전적인 행동이다.
  • 요청 매개 변수가 URL에 있으면이 앱을 개발하고 디버깅하기가 더 쉽습니다.
  • API는 널리 사용되지 않습니다.
  • 본문이없는 POST 요청을 만드는 데 약간의 작업이 필요합니다. 예를 들어 Content-Length: 0헤더를 명시 적으로 추가해야합니다.
  • 또한 본문이없는 POST는 대부분의 개발자 및 HTTP 프레임 워크의 기대에 약간 반대되는 것으로 보입니다.

요청 본문이 아닌 URL 쿼리를 통해 POST 요청에서 매개 변수를 보내는 데 더 많은 함정이나 장점이 있습니까?

편집 : 이것이 고려중인 이유는 작업이 dem 등성이 아니며 검색 이외의 부작용이 있기 때문입니다. HTTP 스펙을 참조하십시오 .

특히, GET 및 HEAD 방법은 검색 이외의 조치를 취하지 않아야한다는 협약이 확립되었습니다. 이 방법들은 "안전한"것으로 간주되어야합니다. 이를 통해 사용자 에이전트는 POST, PUT 및 DELETE와 같은 다른 방법을 특별한 방식으로 표현할 수 있으므로 안전하지 않은 조치가 요청되고 있다는 사실을 사용자에게 알릴 수 있습니다.

...

또한 메소드는 "오류 또는 만기 문제를 제외하고"N> 0 동일한 요청의 부작용이 단일 요청의 부작용과 동일하다는 점에서 "등전위"특성을 가질 수 있습니다. GET, HEAD, PUT 및 DELETE 메소드는이 특성을 공유합니다. 또한, OPTIONS와 TRACE 메소드는 부작용이 없어야하며, 따라서 본질적으로 dem 등호입니다.


11
본문에 데이터를 제공하지 않으려면 왜 POST를 사용합니까?
Sunny Milenov

114
조작이 dem 등원이 아니기 때문입니다.
Steven Huwig

20
@Jared, 2.5 년 전부터이 질문에 "REST"라는 단어가 나타나지 않습니다. :) dem 등성에 대한 HTTP 사양은 웹 서비스에 대한 월별 아키텍처가 무엇이든 관계없이 적용됩니다. 운 좋게도이 API가 프록시하도록 설계된 시스템은 어쨌든 사용되지 않습니다.
Steven Huwig

5
서버 로그는 POST 매개 변수를 기록하지 않지만 쿼리 문자열을 기록합니다. 브라우저에서 요청하지 않고 일련의 요청을 실행 한 다음 클릭을하는 것보다 역 추적을 보는 것이 훨씬 쉽습니다. 또한 API는 브라우저 대 서버가 아니라 서버 대 서버였습니다. 가장 중요한 것은 어쨌든 전체 사건이 통조림 된 것입니다. :)
Steven Huwig

13
dem 등원의 의미를 모르는 다른 사람을 위해 : | restapitutorial.com/lessons/idempotency.html
Christopher Grigg

답변:


259

행동이 dem 등원이 아닌 경우 반드시를 사용해야 POST합니다. 당신이하지 않으면, 당신은 단지 라인 다운 문제를 요구하고 있습니다. GET, PUTDELETE하는 방법이 필요 멱등한다. 클라이언트가 GET서비스에 대한 가능한 모든 요청을 프리 페치 (pre-fetch) 한 경우 애플리케이션에서 어떤 일이 발생하는지 상상해보십시오. 만약 이것이 클라이언트에게 부작용을 보일 수 있다면 문제가있는 것입니다.

POST쿼리 문자열을 사용하여 본문 을 보내지 않는 것이 이상하게 보이지만 일부 상황에서는 적절하다고 생각합니다.

URL의 쿼리 부분을 리소스에 대한 명령으로 생각하여 현재 요청의 범위를 제한하십시오. 일반적으로 쿼리 문자열은 GET요청 을 정렬하거나 필터링하는 데 사용 ?page=1&sort=title되지만 (예 :) POST범위를 제한 하는 것이 좋습니다 (아마도 같은 ?action=delete&id=5).


4
이 특정 경우에 대해이 답변을 선택했지만 R. Bemrose의 주장은 공개 API에 강렬하다고 생각합니다.
Steven Huwig 2016 년

4
나는 그의 대답이 엄격하다고 생각하지 않습니다. HTML 페이지가 클라이언트로 전송 될 때 양식 게시물의 URL 매개 변수를 알고있는 경우 해당 URL 매개 변수를 양식의 조치 속성에 고정 할 수 있습니다. 그렇지 않으면 양식을 제출할 때 JavaScript가 URL 매개 변수를 설정할 수 있습니다.
Don McCaughey

3
쿼리 매개 변수가있는 URL에 XML 파일을 게시하는 것은 어떻습니까? 가능합니까?
OpenCoderX 2013

3
또 다른 예 : 요청 데이터는 http 엔터티에있을 수 있지만 요청 된 응답 형식은 쿼리 매개 변수 ( /action?response_format=json)
rds

4
+1은 오늘 무언가를 배웠습니다. 삭제 기술은 dem 등원입니다. 객체가 실제로 삭제되면 404를 찾을 수 없으므로 서버의 상태는 동일하지만 응답은 달라집니다. Cow Picture : restapitutorial.com/lessons/idempotency.html
JPK

131

모든 것이 옳습니다 : 비등 전성 요청에 POST를 사용하십시오.

URI 쿼리 문자열과 요청 내용을 모두 사용하는 것은 어떻습니까? 글쎄, 그것은 유효한 HTTP입니다 (주 1 참조), 왜 그렇지 않습니까?!

쿼리 문자열 부분을 포함한 URL은 리소스 를 찾기 위한 것입니다. HTTP 메소드 동사 (POST-및 선택적 요청 컨텐츠)는 조치 또는 자원 으로 수행 할 작업을 지정하기위한 것입니다 . 그것들은 직교 관심사 여야합니다. 그러나 ContentType = application / x-www-form-urlencoded의 특수한 경우에 대해서는 직교적인 문제가 아닙니다. 아래 참고 2를 참조하십시오.

참고 1 : HTTP 사양 (1.1)에는 쿼리 매개 변수와 내용이 POST 또는 PUT 요청을 수락하는 HTTP 서버에 대해 상호 배타적이라고 명시되어 있지 않습니다. 따라서 모든 서버는 두 가지를 모두 수용 할 수 있습니다. 즉, 서버를 작성하면 융통성이없는 프레임 워크를 제외하고 두 가지를 모두 선택하도록 막을 수있는 것이 없습니다. 일반적으로 서버는 원하는 규칙에 따라 쿼리 문자열을 해석 할 수 있습니다. Content-Type과 같은 다른 헤더를 참조하는 조건부 논리로 해석 할 수도 있습니다.

참고 2 : 경우 웹 브라우저는 사람들이 웹 응용 프로그램에 액세스하는 기본 방법이며, 응용 프로그램 / x-www-form-urlencoded를이 는 IS 당신은 그들이 게시하는 콘텐츠를 입력 해야 하는 콘텐츠 형식에 대한 규칙을 따릅니다. 그리고 application / x-www-form-urlencoded에 대한 규칙은 훨씬 더 구체적이고 솔직한 경우도 있습니다.이 경우 URI를 리소스 위치가 아닌 매개 변수 집합으로 해석해야합니다. [이것은 파워로드가 제기 한 것과 같은 유용성의 지점이다. 웹 양식을 사용하여 서버에 컨텐츠를 게시하는 것이 어려울 수 있습니다. 조금 다르게 설명했습니다.]

참고 3 : 쿼리 문자열은 원래 무엇입니까? RFC 3986은 HTTP 쿼리 문자열을 자원을 찾는 비 계층 적 방식으로 작동하는 URI 부분으로 정의합니다.

이 질문을하는 독자들이 좋은 RESTful 아키텍처가 무엇인지 묻고 자하는 경우 RESTful 아키텍처 패턴은 URI 방식이 특정 방식으로 작동하지 않아도됩니다. RESTful 아키텍처는 리소스의 캐시 가능성, 리소스 자체의 디자인 (동작, 기능 및 표현), dem 등원 충족 여부와 같은 시스템의 다른 속성과 관련이 있습니다. 즉, HTTP 프로토콜 및 HTTP 메소드 동사 세트와 매우 호환되는 디자인을 달성하십시오. :-) (즉, RESTful 아키텍처는 리소스의 위치를 잘 예측하지 못합니다 .)

마지막 참고 사항 : 때로는 쿼리 매개 변수가 리소스를 찾거나 콘텐츠를 인코딩하지 않는 다른 용도로 사용됩니다. 'PUT = true'또는 'POST = true'와 같은 쿼리 매개 변수를 본 적이 있습니까? PUT 및 POST 방법을 사용할 수없는 브라우저에 대한 해결 방법입니다. 이러한 매개 변수는 URL 쿼리 문자열 (전선)의 일부로 볼 수 있지만 정신적으로 URL 쿼리의 일부가 아니라고 주장합니다 .


66

이유를 원하십니까? 여기 하나가 있습니다 :

웹 양식을 사용하여 GET과 POST가 혼합 된 페이지로 요청을 보낼 수 없습니다. 양식의 메소드를 GET으로 설정하면 모든 매개 변수가 조회 문자열에 있습니다. 양식의 메소드를 POST로 설정하면 모든 매개 변수가 요청 본문에 있습니다.

출처 : HTML 4.01 표준, 섹션 17.13 양식 제출


10
그것은 괜찮은 논쟁이지만, 현대 브라우저의 자바 스크립트 구현은 일종의 논쟁 점이라고 생각합니다. 나는 그것에 대해 생각할 것입니다-그것은 미래를 보장하는 방식으로 강렬합니다. 양식을 사용하지 않는다고해서 나중에 원치 않는 것은 아닙니다.
Steven Huwig

9
GET을 POST와 혼합하는 것은 정말 나쁜 생각입니다.
aehlke

6
해당 스 니펫은 귀하가 링크 한 페이지에 나타나지 않습니다
Gareth

40
그러나 method 속성은 "양식 데이터 세트"가 요청에 포함되는 방법을 정의합니다. (가) 때 methodPOST 인 양식의의 URI 변경에 대한 언급이 없다 action. 물론 모든 URI는 이미 쿼리 문자열 부분을 포함 할 수 있습니다.
Gareth

16
@Powerlord 이것은 잘못되었습니다. 예를 들어 조치를 POST로 설정하십시오. /Books?bookCode=1234. 웹 서버는 POST 형식의 변수와 쿼리 문자열을받습니다.
Jez

9

프로그래밍 관점에서 볼 때 클라이언트의 경우 매개 변수를 패키징하여 URL에 추가하고 POST와 GET을 수행합니다. 서버 측에서는 게시 된 바이트 대신 쿼리 문자열에서 인바운드 매개 변수를 평가합니다. 기본적으로 세탁입니다.

장점 / 불이익이있을 수있는 곳은 특정 클라이언트 플랫폼이 네트워킹 스택에서 POST 및 GET 루틴을 처리하는 방법과 웹 서버가 이러한 요청을 처리하는 방법에있을 수 있습니다. 구현에 따라 한 방법이 다른 방법보다 더 효율적일 수 있습니다. 그것이 당신의 결정에 도움이 될 것임을 아는 것.

그럼에도 불구하고 프로그래머의 관점에서 본문에 모든 매개 변수가있는 POST 또는 URL의 모든 매개 변수가있는 GET을 허용하고 POST 요청에서 URL 매개 변수를 명시 적으로 무시하는 것을 선호합니다. 혼란을 피합니다.


8

콘텐츠 페이로드를 POST 본문에 국한시키지 않고 URL의 리소스를 식별하는 쿼리 인수를 갖는 것이 여전히 RESTful 일 수 있다고 생각합니다. 이것은 "무엇을 보내고 있습니까?"에 대한 고려 사항을 분리 한 것으로 보입니다. "누가 그것을 보냅니 까?"


5
질문은 REST에 관한 것이 아닙니다.
Steven Huwig

3
@ user359996 모든 HTTP API가 RESTful 인 것은 아닙니다. 실제로 대부분의 API는 실제로 그렇지 않다고 주장합니다. 또한 재미있는 사실은 REST도 HTTP 전용이 아닙니다.
Alec Mev

4

REST의 캠프는 우리가 HTTP 동사를 사용하는 방법을 표준화하는 데 사용할 수있는 몇 가지 원칙이있다. 이는 RESTful API를 빌드 할 때 유용합니다.

간단히 말해서 : GET은 읽기 전용이어야합니다. 즉 서버 상태에 영향을 미치지 않습니다. POST는 서버에서 리소스를 만드는 데 사용됩니다. PUT은 자원을 업데이트하거나 작성하는 데 사용됩니다. DELETE는 리소스를 삭제하는 데 사용됩니다.

즉, API 조치가 서버 상태를 변경하는 경우 REST는 POST / PUT / DELETE를 사용하도록 권장하지만 GET은 사용하지 않는 것이 좋습니다.

사용자 에이전트는 일반적으로 여러 POST를 수행하는 것이 좋지 않다는 것을 이해합니다. POST의 의도는 서버 상태를 변경하는 것 (예 : 결제시 상품 비용 지불)이므로 두 번 수행하고 싶지는 않습니다.

원하는대로 자주 할 수있는 GET과 비교하십시오 (idempotent).


13
REST 캠프는 HTTP 사양에 정의 된대로 HTTP를 사용해야한다고 말합니다. 즉 RFC2616 그 이상도 그 이하도 아닙니다.
Darrel Miller

1
@Darrel 참조 ibm.com/developerworks/webservices/library/ws-restful : REST는 개발자에게 프로토콜 정의와 일치하는 방식으로 HTTP 메소드를 명시 적으로 사용하도록 요청합니다. 이 기본 REST 설계 원칙은 CRUD (작성, 읽기, 업데이트 및 삭제) 조작과 HTTP 메소드간에 일대일 맵핑을 설정합니다. 이 맵핑에 따르면 : 서버에서 자원을 작성하려면 POST를 사용하십시오. 자원을 검색하려면 GET을 사용하십시오. 자원 상태를 변경하거나 업데이트하려면 PUT을 사용하십시오. 자원을 제거하거나 삭제하려면 DELETE를 사용하십시오.
saille

5
미안하지만 그저 평범한 잘못이야 REST는 균일 한 인터페이스를 준수해야합니다. HTTP를 사용하는 경우 해당 균일 한 인터페이스는 RFC 2616에 의해 부분적으로 정의됩니다. 해당 사양에서는 작성, 읽기, 업데이트 및 삭제와 HTTP 메소드간에 일대일 맵핑이 없습니다.
Darrel Miller

3
GET 및 DELETE는 CRUD의 읽기 및 삭제에 매우 잘 맞지만 업데이트 및 작성에 PUT / POST를 사용하는 것은 간단하지 않습니다.
dcstraw를

5
이 6 년 후를 되돌아 보면, ~ 100k 번 질문을 보았을 때 작은 업데이트를 적용 할 가치가 있다고 생각합니다. Darrel은 Fielding의 REST 정의 ( ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm ) 에 따라 정확합니다 . HTTP 동사를 CRUD에 매핑하는 것에 대한 언급은 없습니다. IBM의 개발자 조언 (위의 설명 링크)은 Fielding의 REST 정의가 아닌 RESTful API 구현의 일반적인 관행을 반영합니다.
세일

-13

동의합니다-본문이 아닌 URL로 데이터를 전달하는 경우 GET 요청을 사용하는 것이 더 안전합니다. 전체 POST + GET 개념에 대한 몇 가지 추가 견해에 대해서는 이 비슷한 질문 을 참조하십시오 .


17
조작에 부작용이있는 경우, 브라우저가 모든 GET이 pot 등원이라고 가정하기 때문에 GET 방법을 사용하는 것이 '안전하지 않습니다'.
dcstraw

구글은 GET 요청과 함께 모든 링크를 안전하게 "클릭"하지만 다른 모든 것은 생략하기 때문에 검색 엔진은 악몽에 그것을 변환합니다. 무고한 크롤러가 실수로 데이터베이스를 지울 수있는 서비스를 떠나는 것은 안전하지 않습니다.
Alejandro
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.