REST에서 PUT과 POST


5372

HTTP / 1.1 사양에 따르면 :

POST방법은 원 서버가 요청에 동봉 된 엔티티를에 의해 식별 된 자원의 새로운 하위로 수락하도록 요청하는데 사용된다 Request-URI.Request-Line

즉, POST만드는 데 사용됩니다 .

PUT메소드는 동봉 된 엔티티가 제공된 아래에 저장되도록 요청합니다 Request-URI. Request-URI참조가 이미 존재하는 자원을 언급하는 경우 동봉 된 엔티티는 원래 서버에있는 엔티티의 수정 된 버전으로 간주해야합니다. (가) 경우 Request-URI기존 자원을 가리 키지 않고, URI는 요청하는 사용자 에이전트에 의하여 새로운 자원으로서 정의 될 수있는 것으로, 원 서버는 그 URI와 리소스를 생성 할 수있다. "

즉, PUT만들거나 바꾸는 데 사용됩니다 .

리소스를 만드는 데 어떤 것을 사용해야합니까? 아니면 둘 다 지원해야합니까?


56
HTTPbis의 정의를 사용하는 것이 도움이 될 수 있습니다. Roy는이를 명확히하는 데 상당한 노력을 기울였습니다. 다음을 참조하십시오 : tools.ietf.org/html/…
Mark Nottingham

16
@MarkNottingham의 의견을 최신 개정판으로 가져 오려면 HTTPbis에 정의 된 POSTPUT이 있습니다.
Marius Butuc 1

37
이 토론은 CRUD 작업의 관점에서 HTTP 메소드를 설명함으로써 REST를 지나치게 단순화하는 일반적인 관행에서 비롯된 것 같습니다.
Stuporman

5
불행히도 첫 번째 답변은 POST에 대해 잘못되었습니다. 차이점에 대한 자세한 설명은 내 대답을 확인하십시오. stackoverflow.com/a/18243587/2458234
7hi4g0

23
PUT과 POST는 모두 안전하지 않은 방법입니다. 그러나 PUT은 dem 등원이지만 POST는 그렇지 않습니다. - 더에서 : restcookbook.com/HTTP%20Methods/put-vs-post/...
네쉬 Saini

답변:


4238

사무용 겉옷:

PUT과 POST는 모두 생성에 사용될 수 있습니다.

"무슨 행동을하고 있습니까?" 사용해야 할 것을 구별하기 위해. 질문을하기위한 API를 디자인한다고 가정 해 봅시다. POST를 사용하려면 질문 목록을 작성하십시오. PUT을 사용하려면 특정 질문에 대해 PUT을 사용하십시오.

둘 다 사용할 수 있으므로 RESTful 디자인에서 어느 것을 사용해야합니까?

PUT과 POST를 모두 지원할 필요는 없습니다.

사용되는 것은 당신에게 달려 있습니다. 그러나 요청에서 참조하는 객체에 따라 올바른 것을 사용하십시오.

몇 가지 고려 사항 :

  • 작성한 URL 객체의 이름을 명시 적으로 지정합니까, 아니면 서버가 결정하도록 하시겠습니까? 이름을 지정하면 PUT을 사용하십시오. 서버가 결정하게하면 POST를 사용하십시오.
  • PUT은 dem 등원이므로 개체를 두 번 PUT하면 아무런 효과가 없습니다. 이것은 좋은 속성이므로 가능한 경우 PUT을 사용합니다.
  • 동일한 객체 URL로 PUT을 사용하여 자원을 업데이트하거나 작성할 수 있습니다.
  • POST를 사용하면 URL을 수정하는 동시에 2 개의 요청을 수신 할 수 있으며 오브젝트의 다른 부분을 업데이트 할 수 있습니다.

예를 들면 :

나는 이것에 관한 SO에 대한 또 다른 대답의 일부로 다음을 썼습니다 .

게시하다:

자원 수정 및 업데이트에 사용

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

다음은 오류입니다.

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

URL이 아직 작성되지 않은 경우 이름을 지정하는 동안 POST를 사용하여 URL을 작성하지 않아야합니다. <new_question>아직 존재하지 않기 때문에 '리소스를 찾을 수 없음'오류가 발생 합니다. <new_question> 먼저 서버 의 리소스를 넣어야 합니다.

POST를 사용하여 리소스를 만들기 위해 이와 같은 작업을 수행 할 수 있습니다.

POST /questions HTTP/1.1
Host: www.example.com/

이 경우 리소스 이름을 지정하지 않으면 새 객체 URL 경로가 반환됩니다.

놓다:

리소스를 만들거나 덮어 쓰는 데 사용됩니다. 자원을 새 URL로 지정하는 동안.

새로운 자료 :

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

기존 리소스를 덮어 쓰려면

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

또한 RFC 7231 섹션 4.3.4 PUT 상태 (강조 추가)

4.3.4. 놓다

PUT 메소드는 대상 자원 의 상태가 요청 메시지 페이로드에 포함 된 표시에 의해 정의 된 상태 created또는 replaced상태가되도록 요청합니다.


1026
PUT이 dem 등 적이라는 사실을 충분히 강조 할 수 없다고 생각합니다. 네트워크가 중단되어 클라이언트가 요청을 통과했는지 확실하지 않은 경우, 두 번째 (또는 100 번째) 시간 만 보내면됩니다. HTTP 스펙은 한 번 전송하는 것과 정확히 동일한 효과를 갖습니다.
Jörg W Mittag 2016 년

77
@ Jörg W Mittag : 필요하지 않습니다. 요청이 그 동안 (다른 사용자 또는 첫 번째 요청 자체에 의해) 수정 된 경우 두 번째는 409 충돌 또는 무언가를 리턴 할 수 있습니다.
Mitar

632
내가 실수하지 않으면, 우리가 강조해야 할 것은 PUT이 dem 등원으로 정의 되어 있다는 것입니다. PUT이 올바르게 동작하는 방식으로 서버를 작성해야합니다. 아마도 "PUT은 전송이 dem 등원을 가정하도록하며, 이는 전송의 동작 (예 : 캐싱)에 영향을 줄 수 있습니다."라고 말하는 것이 좋습니다.
Ian Ni-Lewis

150
@ JörgWMittag Idempotence catchphrase? 어떻습니까? "친구를 보내고 보내고 보내도 결국에는 아무런 차이가 없습니다."
James Beninger

39
PUT = 삽입 또는 업데이트; POST = 삽입 따라서 두 개의 PUT을 만들 때 하나의 새 레코드를 얻고 두 개의 POST를 할 때 두 개의 새 레코드를 얻습니다.
Eugen Konkov

2218

웹에서 다음과 같은 어설 션을 찾을 수 있습니다.

둘 다 옳지 않다.


동작의 dem 등성 에 따라 PUT과 POST 중에서 선택하는 것이 좋습니다.

PUT 은 자원을 넣는 것을 의미합니다. 주어진 URL에서 사용 가능한 모든 것을 다른 것으로 완전히 대체합니다. 정의상 PUT은 dem 등원입니다. 원하는만큼 여러 번하면 결과는 같습니다. x=5dem 등이다. 리소스의 존재 여부에 관계없이 리소스를 PUT 할 수 있습니다 (예 : 생성 또는 업데이트)!

POST 는 리소스를 업데이트하거나 보조 리소스를 추가하거나 변경을 유발합니다. POST는 dem 등성이 아닌 방식으로 x++dem 등성이 아닙니다.


이 인수에 의해, PUT은 작성할 것의 URL을 알 때 작성하기위한 것입니다. POST를 사용하여 만들려는 항목의 범주에 대한 "공장"또는 관리자의 URL을 알고있을 때 만들 수 있습니다.

그래서:

POST /expense-report

또는:

PUT  /expense-report/10929

72
나는 dem 등식이 우려되는 곳이라면 어디든지 잘못하면 많은 예기치 않은 버그가 발생할 수 있기 때문에 다른 우려를 능가해야한다는 데 동의합니다.
Josh

16
POST가 리소스를 업데이트 할 수 있다면 어떻게 dem 등성이 아닌가? PUT을 사용하여 학생 연령을 변경하고 한 번 수행하면 학생 연령이 10x 배가됩니다.
잭 Ukleja

28
@Schneider,이 경우 서버는 dem 등식을 보장하기 위해 추가 노력을 기울이고 있지만 광고는 아닙니다. 브라우저는 POST 요청을 다시로드하려고 할 때 여전히 사용자에게 경고합니다.
Tobu

47
@Schneider POST는 보조 리소스를 만들 수 있습니다. 따라서 POST / expense-reports 와 같이 POST를 수집 할 수 있으며, 완전히 유사한 경우에도 서버에서 보낸 요청 수만큼 많은 엔티티 (비용 보고서)를 작성합니다. 자동 증가 기본 키를 사용하여 DB 테이블 (/ expense-reports)에 동일한 행을 삽입하는 것으로 생각하십시오. 데이터는 동일하게 유지되며 키 (이 경우 URI)는 서버에 의해 생성되며 다른 삽입 (요청)마다 다릅니다. 따라서 POST 효과 dem 등원 일 수 있지만 그렇지 않을 수도 있습니다 . 따라서 POST는 dem 등성이 아닙니다 .
Snifff

11
하자 우리는 두 가지 속성을 가질 수있다 실체가 있다고 - namedate. 우리가 실체가있는 경우 기존 namedate, 그러나 단지 지정이 요청을은 name, 적절한 행동 PUT는 말살하는 것입니다 date반면, 엔티티의를 POST는 속성 만 지정 업데이트 할 수가 있었다으로 지정되지 않은 속성을 떠나, 요청하기 전에. 그 소리가 정확하고 합리적입니까, 아니면 PUT을 부적절하게 사용하고 있습니까? ( PATCH에 대한 참조를 보았습니다 .
Jon z

707
  • URL로 POST서버 정의 URL에 하위 자원작성합니다 .
  • URL로 PUT클라이언트가 정의한 URL 에서 전체적으로 리소스생성 / 대체합니다 .
  • URL로 PATCH 는 해당 클라이언트 정의 URL에서 자원의 일부업데이트합니다 .

PUT 및 POST에 대한 관련 사양은 RFC 2616 §9.5ff입니다.

POST는 하위 자원/items작성 하므로 POST 는 자원 아래에있는 /items자원 을 작성 합니다. 예 : /items/1. 동일한 포스트 패킷을 두 번 보내면 두 개의 리소스가 만들어집니다.

PUT클라이언트가 알고 있는 URL 에서 자원을 작성하거나 대체하기위한 것 입니다.

따라서 PUT 은 리소스가 생성되기 전에 클라이언트가 이미 URL을 알고있는 CREATE의 후보 일뿐입니다. 예 : /blogs/nigel/entry/when_to_use_post_vs_put제목이 리소스 키로 사용되므로

PUT 은 알려진 URL의 자원이 이미 존재하는 경우이를 대체하므로 동일한 요청을 두 번 보내는 것은 효과가 없습니다. 즉, PUT 호출은 dem 등원 입니다.

RFC는 다음과 같습니다.

POST와 PUT 요청의 근본적인 차이점은 Request-URI의 다른 의미에 반영됩니다. POST 요청의 URI는 동봉 된 엔터티를 처리 할 리소스를 식별합니다. 해당 리소스는 데이터 수락 프로세스, 다른 프로토콜의 게이트웨이 또는 주석을 허용하는 별도의 엔터티 일 수 있습니다. 반대로 PUT 요청의 URI는 요청으로 둘러싸인 엔티티를 식별합니다. 사용자 에이전트는 어떤 URI가 의도되어 있는지 알고 서버는 요청을 다른 자원에 적용해서는 안됩니다. 서버가 요청을 다른 URI에 적용하기를 원하는 경우,

참고 : PUT은 주로 전체를 교체하여 리소스를 업데이트하는 데 사용되었지만 최근에는 PUT이 전체 리소스를 교체하도록 지정하므로 기존 리소스를 업데이트하기 위해 PATCH를 사용하는 방향으로 이동하고 있습니다. RFC 5789.

2018 업데이트 : PUT을 피할 수있는 경우가 있습니다. 참조 "PUT없이 REST를"

"PUT없는 REST"기술을 사용하면 소비자는 새로운 'ununified'요청 리소스를 게시해야합니다. 앞에서 설명한 것처럼 고객의 우편 주소 변경은 다른 우편 주소 필드 값을 가진 "고객"자원의 PUT이 아닌 새로운 "ChangeOfAddress"자원에 대한 POST입니다.

에서 가져온 인 ThoughtWorks의 프라 카쉬 Subramaniam에 의해 자원 모델링 - REST API 디자인

이를 통해 API는 단일 클라이언트를 업데이트하는 여러 클라이언트의 상태 전이 문제를 피하고 이벤트 소싱 및 CQRS와 더 잘 일치합니다. 작업이 비동기 적으로 수행되면 변환을 POST하고 적용되기를 기다리는 것이 적절 해 보입니다.


53
또는 펜스의 다른 쪽에서 : 클라이언트가 결과 리소스의 주소를 결정하면 PUT, 서버가 처리하면 POST.
DanMan

3
@DanMan이 매우 간단한 방법으로 지적한 것을 더 명확하게하기 위해이 답변을 편집해야한다고 생각합니다. 내가 여기서 가장 소중하게 생각하는 것은 PUT이 전체 리소스를 교체하는 데에만 사용해야한다는 마지막 노트입니다.
헤르메스

3
PATCH는 최소한 몇 년 동안 현실적인 옵션은 아니지만 이념에 동의합니다.
호감

4
이해하려고 노력하고 있지만 PUT을 사용하여 무언가를 생성하는 것은 클라이언트가 리소스가 아직 존재하지 않는다는 것을 확실히 알고있는 경우에만 의미가 있습니다. 블로그 예에 따라 2 년 동안 수백 개의 블로그 게시물을 만든 다음 2 년 전 게시물과 동일한 제목을 실수로 선택했다고 가정 해 보겠습니다. 이제 의도하지 않은 해당 게시물을 찾아서 교체했습니다. 따라서 PUT을 사용하여 작성하는 것은 클라이언트가 수행 된 작업과 그렇지 않은 작업을 추적해야하며 사고와 의도하지 않은 부작용을 유발할 수있을뿐만 아니라 완전히 다른 두 가지 작업을 수행하는 경로를 가질 수 있습니까?
galaxyAbstractor

5
당신이 올바른지. 기존 게시물과 동일한 URL에 블로그 게시물을 올리면 기존 게시물에 대한 업데이트가 발생합니다 (물론 GET으로 먼저 확인할 수는 있음). 이것은 제목 만 URL로 사용하는 것이 좋지 않은 이유를 나타냅니다. 그러나 데이터에 자연스러운 열쇠가있는 곳이라면 어디에서나 작동 할 것입니다 ... 내 경험으로는 드문 경우입니다. 또는 당신은 GUID를 사용하는 경우
나이젤 쏜를

221

요약:

창조하다:

다음과 같은 방식으로 PUT 또는 POST로 수행 할 수 있습니다.

놓다

생성 새로운 자원 newResourceId 은 / 자원 URI 또는 아래의 식별자를 수집 .

PUT /resources/<newResourceId> HTTP/1.1 

게시하다

작성 은 / 자원 URI, 또는 아래에 새로운 자원을 수집 . 일반적으로 식별자는 서버에서 반환합니다.

POST /resources HTTP/1.1

최신 정보:

다음과 같은 방식으로 PUT으로 수행 할 있습니다.

놓다

/ resources URI 또는 collection 에서 식별자 로 existingResourceId 를 사용 하여 자원을 업데이트합니다 .

PUT /resources/<existingResourceId> HTTP/1.1

설명:

일반적으로 REST와 URI 처리 할 때, 당신은 일반적인왼쪽특정 상의 권리 . 제네릭은 보통이라고 컬렉션 과 더 특정의 항목을 호출 할 수 있습니다 자원 . • 그래도 참고 자원이 포함 할 수있는 모음 .

예 :

<-일반-특정->

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

POST를 사용하면 항상 collection을 참조 하므로 다음과 같이 말할 때마다 :

POST /users HTTP/1.1

새로운 사용자를 users 컬렉션에 게시합니다 .

계속해서 다음과 같이 해보십시오 :

POST /users/john HTTP/1.1

작동하지만 의미 상 사용자 콜렉션 아래의 john 콜렉션 에 자원을 추가하려고합니다 .

일단 PUT을 사용하고 있다면 아마도 콜렉션 내부의 자원 또는 단일 항목을 참조 하는 것 입니다 . 그래서 당신이 말할 때 :

PUT /users/john HTTP/1.1

서버 업데이트를 알리거나 사용자 콜렉션 아래에 john 자원 이없는 경우 작성하십시오 .

투기:

스펙의 중요한 부분을 강조하겠습니다 :

게시하다

POST의 방법은 원 서버가 해당 요청에 사용되는 동의를 A와 요청에 포함 된 엔터티 하위 Request-Line의 Request-URI에 의해 식별되는 자원을

따라서 컬렉션 에 새 리소스 를 만듭니다 .

놓다

PUT에 동봉 될 엔티티가 요청 방법 저장된 제공된 요청-URI하에. Request-URI가 이미 존재하는 자원을 참조하는 경우 동봉 된 엔티티는 원래 서버에 있는 수정 된 버전 으로 간주해야 합니다. Request-URI가 기존 자원을 가리 키지 않고 요청 사용자 에이전트 가 해당 URI를 자원 으로 정의 할 수있는 경우, 원래 서버는 해당 URI로 자원을 작성할있습니다 . "

따라서 자원의 존재에 따라 작성하거나 업데이트하십시오 .

참고:


11
이 게시물은 POST가 지정된 컬렉션 (URI)에 하위 항목으로 "무언가"를 추가하는 반면 PUT은 지정된 URI 위치에서 "무언가"를 명시 적으로 정의한다는 것을 이해하는 데 도움이되었습니다.
kwah

3
이것이 최선의 대답입니다. 여기에서는 "POST가 리소스를 업데이트 할 수 없습니다"라는 말이 없습니다. "PUT으로 만 업데이트를 수행 할 수 있습니다"라는 말이 마음에 듭니다.
토마스

4
아니요, PUT은 업데이트 또는 생성 용이 아닙니다. 교체 용입니다. 생성 효과를 위해 아무것도 대체 할 수 없습니다.
thecoshman

2
@ 7hi4g0 PUT은 완전한 교체로 업데이트하기위한 것입니다. 즉, 교체합니다. 당신은 아무것도 다른 것으로 대체하거나 완전히 새로운 것으로 대체합니다. PUT은 사소한 변경을위한 것이 아닙니다 (클라이언트가 사소한 변경을하고 새 버전 전체를 제공하지 않는 한 동일하게 유지되는 경우는 제외). 부분 수정의 경우 PATCH가 선택되는 방법입니다.
thecoshman 2016 년

1
@thecoshman 당신은 할 수 있지만, create도 그 안에 포함되어 있다는 것이 너무 명확하지 않습니다. 이 경우 명시 적으로 작성하는 것이 좋습니다.
7hi4g0

175

POST "여기서 사용자를 작성하고 입력하십시오"와 같이 "새로 작성"을 의미합니다.

PUT "사용자 5의 데이터는 다음과 같습니다"와 같이 "이미 존재하면 삽입, 교체"를 의미합니다.

당신은 POST당신이 알고하지 않기 때문에 example.com/users에 URL아직 사용자의, 당신은 서버를 만들려고합니다.

당신은 PUT당신이 /로 교체 만들려는 이후 example.com/users/id하는 특정의 사용자.

동일한 데이터로 두 번 게시하면 ID가 다른 두 명의 동일한 사용자가 생성됩니다. 동일한 데이터로 두 번 PUT하면 첫 번째 사용자가 생성되고 두 번째로 동일한 상태로 업데이트됩니다 (변경 사항 없음). PUT여러 번 수행해도 상관없이 동일한 상태로 끝나기 때문에 매번 "동등한"유동성이라고합니다. 요청을 자동으로 재 시도하는 데 유용합니다. 브라우저에서 뒤로 버튼을 누를 때 더 이상 '재전송 하시겠습니까?'

일반적인 조언은 POST서버가 URL자원 생성을 제어 할 필요가있을 때 사용 하는 것입니다 . PUT그렇지 않으면 사용하십시오 . 선호 PUT 이상 POST.


12
부주의로 인해 GET과 POST의 두 가지 동사 만 필요하다는 것이 일반적으로 알려질 수 있습니다. 획득, 변경하려면 POST하십시오. POST를 사용하여 PUT 및 DELETE도 수행되었습니다. PUT이 실제로 25 년 후 무엇을 의미하는지 묻는 것은 처음에 잘못 배웠다는 신호일 수 있습니다. REST 인기는 사람들을 과거의 잘못된 실수를 풀어야 할 기본으로 되돌 렸습니다. POST가 과도하게 사용되었으며 이제는 일반적으로 잘못 학습되었습니다. 가장 중요한 부분 : "동일한 데이터로 두 번 POST를 수행하면 두 개의 동일한 [자원]이 생성됩니다." 좋은 지적입니다!
maxpolk

1
PUT을 사용하여 user 5아직 존재하지 않는 예와 같이 ID로 레코드를 작성하는 방법은 무엇입니까? 당신은 의미하지 update, replace if already exists않습니까? 또는 무엇인가
Luke

@Coulton : 내가 쓴 것을 의미했습니다. / users / 5에 PUT을했지만 # 5가 없으면 사용자 5를 삽입합니다.
Alexander Torstling

@Coulton : 기존 리소스 의 가치를 전체적으로 대체 하는 PUT데 사용될 수도 있습니다 .
DavidRR

1
"PUT보다 PUT 선호"... 정당화 할까?
thecoshman

173

"실용적인"조언을 추가하고 싶습니다. 저장하는 오브젝트를 검색 할 수있는 "id"를 알고있는 경우 PUT을 사용하십시오. 예를 들어 향후 조회 또는 업데이트를 위해 데이터베이스 생성 ID를 반환해야하는 경우 PUT을 사용하면 제대로 작동하지 않습니다.

따라서 : 기존 사용자 또는 클라이언트가 ID를 생성하고 ID가 고유하다는 것을 확인한 사용자를 저장하려면 다음을 수행하십시오.

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

그렇지 않으면 POST를 사용하여 처음에 오브젝트를 작성하고 PUT을 사용하여 오브젝트를 업데이트하십시오.

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com

17
실제로는이어야합니다 POST /users. ( /users복수입니다.) 이는 새 사용자를 작성하여 /users콜렉션 의 하위 자원으로 만드는 영향을 미칩니다 .
DavidRR

6
@DavidRR이 공정해야 그룹을 처리하는 방법은 또 다른 논쟁입니다. GET /users의미가 있지만 원하는 대로 읽지 만 '나에게 사용자 5를 얻으십시오'는 이상하지만 '사용자 5를 얻으십시오'가 더 자연스럽게 읽히기 때문에 GET /user/<id>또는 POST /user(새로운 사용자를위한 페이로드 로) 괜찮 습니다. 나는 아마 여전히 복수형의 측면에 빠질 것입니다 :)
thecoshman

126

POST를 사용하여 생성하고 PUT을 사용하여 업데이트하십시오. 어쨌든 Ruby on Rails는 그렇게하고 있습니다.

PUT    /items/1      #=> update
POST   /items        #=> create

4
POST /items이미 정의 된 리소스 ( 'item')에 새 항목을 추가합니다. 대답에서 알 수 있듯이 "그룹 만들기"는 아닙니다. 왜 12 표를 얻었는지 이해할 수 없습니다.
David J.

Rails는 기본적으로 REST를 통한 '그룹 생성'을 지원하지 않습니다. '자원 만들기'를 의미하는 '그룹 만들기'를하려면 소스 코드를 통해해야합니다.
David J.

8
이것은 공정한 지침이지만 지나치게 단순화 된 것입니다. 다른 답변에서 언급했듯이 두 방법 중 하나를 사용하여 생성 및 업데이트 할 수 있습니다.
Brad Koch

2
나는 약간의 수정으로 대답에 동의합니다. POST를 사용하여 자원을 완전히 업데이트하고 PUT을 작성하십시오. 부분 업데이트의 경우 PUT 또는 PATCH를 사용할 수 있습니다. 그룹의 상태를 업데이트하고 싶다고합시다. 우리는 상태 PUT / 그룹 / 1 / 상태를 요청 페이로드 또는 패치 페이로드의 행동에 대한 세부 / 그룹 / 1 사용할 수 있습니다
java_geek

2
또한 클라이언트가 리소스의 이름을 지정할 권한이있는 경우에만 리소스 PUT /items/42생성 하는데도 유효한지 확인해야합니다 . (Rails는 클라이언트에게이 이름 지정 권한을 허용합니까?)
DavidRR

123

둘 다 클라이언트에서 서버로의 데이터 전송에 사용되지만 이들 사이에는 미묘한 차이가 있습니다.

여기에 이미지 설명을 입력하십시오

유추:

  • 즉, 소요 시간 및 PUT 넣어 그것을 어디에.
  • 우체국 에서 메일 발송으로 POST .

여기에 이미지 설명을 입력하십시오

소셜 미디어 / 네트워크 비유 :

  • 포스트는 소셜 미디어에 : 우리가 메시지를 게시 할 때, 그것은 새 게시물을 작성합니다.
  • 이미 게시 한 메시지를 넣습니다 (예 : 편집).

21
@MobileMon 아니오, REST 메소드는 CRUD가 아닙니다.
jlr

1
나는 UPSERTS에 대한 PUT
Hola Soy Edu Feliz Navidad

@MobileMon no : 새 리소스를 생성하고 최종 엔드 포인트를 모르는 경우 POST. 다른 경우에는 PUT.
Portekoi

67

REST는 매우 높은 수준의 개념입니다. 사실, 그것은 전혀 HTTP를 언급하지 않습니다!

HTTP로 REST를 구현하는 방법에 대해 의문이있는 경우 언제든지 AtomPub (Atom Publication Protocol) 사양을 살펴볼 수 있습니다 . AtomPub는 많은 HTTP 및 REST 조명에 의해 개발 된 HTTP를 사용하여 RESTful 웹 서비스를 작성하기위한 표준이며, REST의 발명자이자 HTTP의 공동 발명자 인 Roy Fielding의 의견이 있습니다.

실제로 AtomPub를 직접 사용할 수도 있습니다. 블로그 커뮤니티에서 나왔지만 블로그에는 제한이 없습니다. HTTP를 통해 임의의 (중첩 된) 임의의 리소스 모음과 RESTful하게 상호 작용하기위한 일반적인 프로토콜입니다. 응용 프로그램을 중첩 된 리소스 모음으로 나타낼 수 있다면 AtomPub을 사용하고 PUT 또는 POST 사용 여부, 반환 할 HTTP 상태 코드 및 모든 세부 정보에 대해 걱정할 필요가 없습니다.

이것이 자원 생성 (섹션 9.2)에 대해 AtomPub가 말한 내용입니다.

컬렉션에 멤버를 추가하기 위해 클라이언트는 POST 요청을 컬렉션의 URI로 보냅니다.


8
PUT이 리소스를 생성하도록 허용하는 데 아무런 문제가 없습니다. 클라이언트가 URL을 제공한다는 의미입니다.
Julian Reschke

5
PUT이 리소스를 생성하도록 허용하는 데에는 매우 잘못된 것이 있습니다. 클라이언트가 URL을 제공합니다. 그것이 서버의 일입니다!
Joshcodes

@Joshcodes 클라이언트 ID를 작성하는 것이 항상 서버의 작업 인 것은 아닙니다. 클라이언트가 일종의 UUID를 리소스 ID로 생성 할 수있는 디자인을 점점 더 많이 보았습니다. 이 디자인은 특히 규모를 늘리기 위해 적합합니다.
저스틴 옴스

@JustinOhms 본인은 클라이언트 생성 ID에 대한 귀하의 의견에 동의합니다 (주의 : 2008 년경 이후 저에 의해 설계된 모든 시스템은 클라이언트가 ID를 UUID / Guid로 생성하도록 요구합니다). 클라이언트가 URL을 지정해야한다는 의미는 아닙니다.
Joshcodes

1
예, 리소스가 이미 존재하는 경우 PUT을 사용하십시오. 그러나 거의 모든 경우에 POST를 사용하여 자원을 작성해야하며 클라이언트는 URL을 제공하지 않아야합니다. Roy Fielding은 다음 진술에 동의합니다. roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Joshcodes

61

PUT 또는 POST를 사용하여 HTTP + REST API가있는 서버에서 자원을 작성할지 여부는 URL 구조의 소유자를 기반으로 결정됩니다. 클라이언트가 URL 구조를 알고 있거나 정의하는 데 참여하면 SOA에서 발생하는 바람직하지 않은 결합과 유사한 불필요한 결합이됩니다. 이스케이프 유형의 커플 링은 REST가 널리 사용되는 이유입니다. 따라서 올바른 사용 방법은 POST입니다. 이 규칙에는 예외가 있으며 클라이언트가 배포 한 리소스의 위치 구조에 대한 제어 권한을 유지하려고 할 때 발생합니다. 이것은 드물고 다른 것이 잘못되었음을 의미합니다.

이 시점에서 일부 사람들은 RESTful-URL 을 사용하면 클라이언트가 리소스의 URL을 알고 있으므로 PUT이 허용 된다고 주장합니다 . 결국, 이것이 정식, 정규화 된 Ruby on Rails, Django URL이 중요한 이유입니다. Twitter API를 살펴보십시오 ... blah blah blah. 그 사람들 은 Restful-URL같은 것이 없으며 Roy Fielding 자신은 다음과 같이 말합니다 .

REST API는 고정 자원 이름 또는 계층 (클라이언트와 서버의 명백한 결합)을 정의해서는 안됩니다. 서버는 자신의 네임 스페이스를 자유롭게 제어 할 수 있어야합니다. 대신, 서버가 클라이언트에게 HTML 형식 및 URI 템플릿에서 수행되는 것과 같은 적절한 URI를 구성하는 방법을 미디어 유형 및 링크 관계 내에서 해당 명령을 정의하여 지시 할 수 있습니다. [여기서 실패는 클라이언트가 RPC의 기능적 커플 링과 동등한 데이터 지향적 인 도메인 별 표준과 같은 대역 외 정보로 인해 자원 구조를 가정하고 있음을 의미합니다.

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

RESTful-URL 에 대한 아이디어는 서버가 URL 구조를 담당하므로 실제로 REST를 위반하는 것이므로 커플 링을 피하기 위해이를 사용하는 방법을 자유롭게 결정할 수 있어야합니다. 이것이 혼란 스러우면 API 디자인에서 자체 발견의 중요성에 대해 읽습니다.

POST는 dem 등원이 아니기 때문에 POST를 사용하여 리소스를 만들 때 디자인 고려 사항이 따릅니다. 이것은 POST를 여러 번 반복한다고해서 매번 같은 동작을 보장하지는 않습니다. 이로 인해 사람들은 PUT을 사용하여 리소스를 생성해서는 안됩니다. 그들은 그것이 틀렸다는 것을 알고 있지만 (POST는 CREATE를위한 것입니다) 그들은이 문제를 해결하는 방법을 모르기 때문에 어쨌든 그렇게합니다. 이 문제는 다음 상황에서 설명됩니다.

  1. 클라이언트는 서버에 새 리소스를 POST합니다.
  2. 서버는 요청을 처리하고 응답을 보냅니다.
  3. 클라이언트는 응답을받지 않습니다.
  4. 서버가 클라이언트가 응답을받지 않았다는 것을 인식하지 못합니다.
  5. 클라이언트에는 리소스에 대한 URL이 없으므로 (PUT은 옵션이 아님) POST를 반복합니다.
  6. POST는 dem 등성이 아니며 서버는 ...

6 단계는 사람들이 무엇을해야할지 혼란스러워하는 곳입니다. 그러나이 문제를 해결하기 위해 kludge를 만들 필요는 없습니다. 대신 RFC 2616에 지정된대로 HTTP를 사용할 수 있으며 서버는 다음과 같이 응답합니다.

10.4.10 409 충돌

자원의 현재 상태와 충돌하여 요청을 완료 할 수 없습니다. 이 코드는 사용자가 충돌을 해결하고 요청을 다시 제출할 수있는 상황에서만 허용됩니다. 응답 본문에는 충분한 내용이 포함되어야합니다

사용자가 충돌의 원인을 인식 할 수있는 정보. 이상적으로, 응답 엔티티는 사용자 또는 사용자 에이전트가 문제를 해결하기에 충분한 정보를 포함 할 것이다. 그러나 불가능할 수도 있고 필요하지 않을 수도 있습니다.

PUT 요청에 대한 응답으로 충돌이 발생할 가능성이 높습니다. 예를 들어, 버전 관리를 사용 중이고 PUT중인 엔티티에 이전 (타사) 요청으로 작성된 자원과 충돌하는 자원에 대한 변경 사항이 포함 된 경우 서버는 409 응답을 사용하여 요청을 완료 할 수 없음을 표시 할 수 있습니다 . 이 경우 응답 엔티티는 응답 Content-Type에 의해 정의 된 형식으로 두 버전 간의 차이점 목록을 포함 할 수 있습니다.

상태 코드 409 충돌로 응답하는 것은 다음과 같은 이유로 올바른 해결책입니다 .

  • 시스템에 이미있는 자원과 일치하는 ID를 가진 데이터의 POST를 수행하는 것은 "자원의 현재 상태와 충돌합니다."
  • 중요한 부분은 클라이언트가 서버에 리소스가 있다는 것을 이해하고 적절한 조치를 취하는 것입니다. "사용자가 충돌을 해결하고 요청을 다시 제출할 수있는 상황"입니다.
  • 충돌하는 ID를 가진 자원의 URL과 자원에 대한 적절한 사전 조건이 포함 된 응답은 RFC 2616에 이상적인 경우 인 "사용자 또는 사용자 에이전트가 문제를 해결하기에 충분한 정보"를 제공합니다.

2616을 대체하기위한 RFC 7231 릴리스에 따른 업데이트

RFC 7231 은 2616을 대체하도록 설계되었으며 4.3.3 절 에서 POST에 대한 다음 가능한 응답을 설명합니다.

POST 처리 결과가 기존 자원의 표현과 동일한 경우, 원 서버는 Location 필드에 기존 자원의 식별자와 함께 303 (기타 참조) 응답을 전송하여 사용자 에이전트를 해당 자원으로 리디렉션 할 수 있습니다. 이는 사용자 에이전트가 이미 캐시 된 표현을 가지고 있지 않은 경우 추가 요청 비용으로 사용자 에이전트에 자원 식별자를 제공하고 공유 캐싱에 더 적합한 방법을 통해 표시를 전송하는 이점이 있습니다.

POST가 반복되는 경우 단순히 303을 반환하려는 유혹이있을 수 있습니다. 그러나 그 반대입니다. 303을 리턴하면 여러 작성 요청 (다른 자원 작성)이 동일한 컨텐츠를 리턴하는 경우에만 의미가 있습니다. 클라이언트가 매번 다시 다운로드 할 필요가없는 "요청 메시지를 제출해 주셔서 감사합니다"가 그 예입니다. RFC 7231은 여전히 ​​4.2.2 섹션에서 POST가 not 등원이 아니며 POST를 작성에 사용해야한다고 계속 유지합니다.

이에 대한 자세한 내용은이 기사를 읽으십시오 .


409 충돌 응답이 이미 존재하는 사용자 이름으로 새 계정을 만들려고 할 때 적합한 코드입니까? 특히 버전 관리 충돌에 409를 사용하고 있지만 답변을 읽은 후 "중복"요청에 사용해서는 안 될지 궁금합니다.
Eric B.

@EricB. 예, "자원의 현재 상태와의 충돌로 인해"설명 된 상황에서는 작업이 실패합니다. 또한 사용자가 충돌을 해결할 수 있으며 메시지 본문은 사용자 이름이 이미 존재한다는 사실 만 사용자에게 알리기 만하면됩니다.
Joshcodes

@Joshcodes 충돌 해결 프로세스에 대해 더 자세히 말할 수 있습니까? 이 경우 사용자 이름이 이미 존재하면 클라이언트는 최종 사용자에게 다른 사용자 이름을 입력하라는 메시지를 표시합니까? 클라이언트가 실제로 POST를 사용하여 사용자 이름을 변경하려고하면 어떻게됩니까? PUT 요청은 여전히 ​​매개 변수 업데이트에 사용해야하는 반면 POST는 한 번에 하나 또는 여러 개의 개체를 만드는 데 사용됩니까? 감사.
BFar

@ BFar2 사용자 이름이 이미 존재하면 클라이언트는 사용자에게 프롬프트를 표시해야합니다. 사용자 이름이 수정이 필요한 이미 생성 된 리소스의 일부라고 가정하면 사용자 이름이 정확하기 때문에 PUT이 사용되고 POST는 생성에 항상 사용되고 PUT은 업데이트에 사용됩니다.
Joshcodes

짧고 효과적인 언어를 사용하는 것을 설명하는 것은 바람직한 기술이다
Junchen 리우

53

나는 RFC 2616의 PUT 정의 에서이 조언을 좋아한다 .

POST와 PUT 요청의 근본적인 차이점은 Request-URI의 다른 의미에 반영됩니다. POST 요청의 URI는 동봉 된 엔터티를 처리 할 리소스를 식별합니다. 이 리소스는 데이터 수락 프로세스, 다른 프로토콜의 게이트웨이 또는 주석을 허용하는 별도의 엔티티 일 수 있습니다. 반대로 PUT 요청의 URI는 요청으로 둘러싸인 엔티티를 식별합니다. 사용자 에이전트는 의도 된 URI를 알고 있으며 서버는 요청을 다른 자원에 적용해서는 안됩니다.

이것은 다른 조언과 함께 PUT이 이미 이름을 가진 리소스에 가장 적합하고 POST는 기존 리소스 아래에 새 객체를 만들고 서버 이름을 지정하는 데 좋습니다.

나는 이것을 의미하며 PUT의 dem 등성 요구 사항을 다음과 같이 해석합니다.

  • POST는 컬렉션에서 새 객체를 만드는 데 유용합니다 (생성 할 필요가 없습니다).
  • PUT은 기존 객체를 업데이트하는 데 좋습니다 (업데이트는 i 등원이어야 함)
  • POST는 기존 객체에 대한 비등 전성 업데이트에도 사용될 수 있습니다 (특히 전체를 지정하지 않고 객체의 일부를 변경하는 경우) 생각하면 컬렉션의 새 멤버를 만드는 것은 실제로 이런 종류의 특별한 경우입니다. 컬렉션의 관점에서 업데이트)
  • 클라이언트가 자원의 이름을 지정할 수있는 경우에만 PUT을 작성에 사용할 수도 있습니다. 그러나 REST 클라이언트는 URL 구조에 대해 가정하지 않아도되므로 의도 된 개념이 아닙니다.

3
"POST는 기존 객체에 대한
비등 전성

48

한마디로 :

PUT 은 dem 등원이며 동일한 작업이 한 번 또는 여러 번 실행될 경우 자원 상태가 동일합니다.

POST 는 비등 전성이므로 단일 시간 실행과 비교하여 작업이 여러 번 실행되는 경우 리소스 상태가 달라질 수 있습니다.

데이터베이스 쿼리와 유추

PUT "UPDATE STUDENT SET address ="abc "와 유사하게 생각할 수 있습니다. 여기서 id ="123 ";

POST "INSERT INTO STUDENT (이름, 주소) VALUES ("abc ","xyzzz ");

학생 ID가 자동으로 생성됩니다.

PUT을 사용하여 동일한 조회가 여러 번 또는 한 번 실행되는 경우 STUDENT 테이블 상태는 동일하게 유지됩니다.

POST의 경우, 동일한 쿼리가 여러 번 실행되면 데이터베이스에 여러 학생 레코드가 생성되고 "INSERT"쿼리가 실행될 때마다 데이터베이스 상태가 변경됩니다.

참고 : PUT에는 업데이트가 필요한 리소스 위치 (이미 리소스)가 필요하지만 POST에는 필요하지 않습니다. 따라서 직관적으로 POST는 새 리소스를 생성하기위한 것이며 PUT은 기존 리소스를 업데이트하는 데 필요합니다.

일부는 POST로 업데이트를 수행 할 수 있습니다. 업데이트에 사용할 규칙이나 만들 때 사용할 규칙은 없습니다. 다시 말하지만 이것은 관습이며, 직관적으로 위에서 언급 한 추론에 관심이 있으며 따르십시오.


6
대한 PUT 과 유사하다 INSERT 또는 UPDATE 쿼리
오이겐 Konkov

1
실제로 PUT "UPDATE STUDENT SET address ="abc "여기서 id ="123 "과 비슷하다고 생각할 수 있습니다 .PATCH에 대한 설명입니다."UPDATE STUDENT SET address = "abc", name = "newname"여기서 id = " 123 "은 PUT에 대한 올바른 비유 일 것입니다.
mko

INSERT에도 Put을 사용할 수 있습니다. 예를 들어, 서버에서 동일한 파일을 여러 번 업로드하려고 시도한 것을 감지하면 요청이 dem 등원이됩니다. (새 파일 업로드는 수행되지 않습니다).
kiwicomb123

43

POST는 편지함에 편지를 올리거나 이메일을 이메일 대기열에 올리는 것과 같습니다. PUT은 물체를 큐비 홀이나 선반 위의 장소 (주소가 알려져 있음)에 놓을 때와 같습니다.

POST를 사용하면 QUEUE 또는 COLLECTION의 주소에 게시됩니다. PUT을 사용하면 ITEM의 주소로 전환됩니다.

PUT은 dem 등원입니다. 요청을 100 번 보낼 수 있으며 중요하지 않습니다. POST는 dem 등성이 아닙니다. 요청을 100 번 보내면 우편함에 100 개의 이메일 또는 100 개의 편지가 발송됩니다.

일반적인 규칙 : 항목의 ID 또는 이름을 알고있는 경우 PUT을 사용하십시오. 수신 측에서 품목의 ID 또는 이름을 지정하려면 POST를 사용하십시오.

POST 대 PUT


1
아니요, PUT은 URL을 알고 있음을 의미합니다. ID 만 알고 있다면 해당 ID로 POST하여 URL을 얻으십시오.
Joshcodes

6
id는 URL의 일부이므로 URL을 알고 있다면 (PID 포함) PUT을 사용하십시오.
호머 6

아니요, URL은 서버에 의해 결정되며 ID는 반드시 URL의 일부일 필요는 없습니다. 로이 필딩 (Roy Fielding)도 똑같이 말 하거나 그의 논문을 읽을 수 있습니다 .
Joshcodes

@Joshcodes, REST를 가정합니까? RESTful 아키텍처에서 항목 ID는 / people / 123과 같이 URL의 일부입니다. 나는이 사이트가 REST를 좋아한다 : microformats.org/wiki/rest/urls
Beez

1
@Beez mircoformats 링크는 서버 가 URL을 구성 하는 좋은 방법을 제안 하지만 서버 는 URL을 결정합니다. 클라이언트는 절대로 그렇지 않습니다. 이것을 이해하지 못하면 내 답변 이나 관련 기사를 참조하십시오 .
Joshcodes

39

새로운 답변 (이제 REST를 더 잘 이해하고 있음) :

PUT은 이제 서비스가 클라이언트가 식별 한 자원의 표현을 렌더링하기 위해 사용해야하는 컨텐츠에 대한 설명 일뿐입니다. POST는 서비스가 어떤 컨텐츠를 포함해야하는지에 대한 진술입니다.

PUT x( 리소스를x 식별하는 경우 ) : " 내 콘텐츠로 식별 된 리소스의 콘텐츠를 교체하십시오 ."x

PUT x( x리소스를 식별 할 수없는 경우 ) : "내 컨텐츠를 포함하는 새 리소스를 생성하고 x식별하는 데 사용하십시오."

POST x: "내 컨텐츠를 저장하고 해당 컨텐츠를 포함하는 자원 (오래된 또는 새로운)을 식별하는 데 사용할 수있는 식별자를 제공하십시오 (다른 컨텐츠와 혼합 될 수 있음). 해당 자원은 동일하거나 종속 된 것이어야합니다 x." " y 의 자원은 x 의 자원에 종속적 "은 일반적으로 yx 의 하위 경로 (예 : x = /fooy = /foo/bar)로 만들고 존재를 반영하기 위해 x 의 자원 표현을 수정하여 반드시 구현되는 것은 아닙니다. 새로운 자원, 예를 들어 y에 대한 하이퍼 링크의 리소스 및 일부 메타 데이터. REST에서는 URL이 불투명하기 때문에 후자 만이 실제로 디자인에 필수적 입니다. 어쨌든 서비스를 통과하기 위해 클라이언트 측 URL 구성 대신 하이퍼 미디어사용해야 합니다.

REST에는 "content"를 포함하는 리소스와 같은 것은 없습니다. 서비스가 표현을 일관되게 표현하기 위해 사용하는 데이터를 "콘텐츠"라고합니다. 일반적으로 데이터베이스 또는 파일 (예 : 이미지 파일)의 일부 관련 행으로 구성됩니다. JSON 페이로드를 SQL 문으로 변환하는 것과 같이 사용자의 컨텐츠를 서비스가 사용할 수있는 것으로 변환하는 것은 서비스에 달려 있습니다.

원래 답변 (읽기 쉬울 수 있음) :

PUT /something( /something이미 존재하는 경우 ) : "당신이 가지고있는 것을 가지고 /something내가 당신에게주는 것으로 바꿉니다."

PUT /something( /something이미 존재하지 않는 경우 ) : "내가 준 것을 가져 가서에 넣으십시오 /something."

POST /something: "내가하는 것을 가져 /something가서 URL을 알려주는 한 원하는 곳에 두십시오 ."


그러나 ID 생성 방법이 Auto Increment 인 상태에서 PUT을 사용하여 새 리소스가 없으면 어떻게 만들 수 있습니까? 일반적으로 ORM은 POST와 같은 방식으로 ID를 자동 생성합니다. PUT을 올바르게 구현하려면 id 자동 생성을 변경해야한다는 의미입니까? 대답이 '예'이면 어색합니다.
Roni Axelrad

1
@RoniAxelrad : PUT은 명령문에 키를 포함하는 데이터베이스 "INSERT OR UPDATE"명령문과 같으므로 충돌을 방지 할 수있는 경우에만 해당됩니다. 예. 도메인에 '자연 키'가 있거나 guid를 사용합니다. POST는 자동 증분 키를 사용하여 테이블에 삽입하는 것과 같습니다. 데이터베이스에 삽입 된 후 얻은 ID를 알려야합니다. "INSERT OR UPDATE"는 이전 데이터가있는 경우이를 대체합니다.
Nigel Thorne

@NigelThorne 답변 주셔서 감사합니다. 예를 들어 URI가있는 책 ID 10을 PUT books / 10으로 PUT하려고합니다. 책 ID 10이 없으면 ID 10을 가진 책을 만들어야합니까? 그러나 자동 증가이므로 생성 ID 분자를 제어 할 수 없습니다. 그 상황에서 어떻게해야합니까?
Roni Axelrad

1
존재하지 않는 ID에 대한 @RoniAxelrad REST PUT은 서버에 자원을 작성하라는 요청입니다. 허용 여부를 결정하는 것은 여전히 ​​서버에 달려 있습니다. 서버가 담당하고 있습니다. "아니요. 그렇게하지 않겠습니다"라고 대답 할 수 있습니다. 사용자에게 충분한 권한이없는 경우 이미 그렇게합니다. 서버가 "아니오"라고 말해도됩니다. REST 우리가 요청의 여러 유형의 의미를 정의 할 수있는 대회입니다 ... 당신의 서버는 "NO"여전히 다음과 같은 것 REST를 :) 말한다하더라도 비즈니스 로직 :)를 기반으로하는 요청을 수행 할 작업을 결정
나이젤 쏜

38

짧은 답변:

간단한 경험 법칙 : POST를 사용하여 생성하고 PUT을 사용하여 업데이트하십시오.

긴 답변 :

게시하다:

  • POST는 서버로 데이터를 보내는 데 사용됩니다.
  • 리소스의 URL을 알 수 없을 때 유용

놓다:

  • PUT은 서버로 상태를 전송하는 데 사용됩니다
  • 자원의 URL을 알고있을 때 유용

더 긴 답변 :

이를 이해하기 위해 PUT이 필요한 이유, PUT이 POST로 해결할 수없는 문제는 무엇인지 질문해야합니다.

REST 아키텍처의 관점에서 중요한 것은 없습니다. 우리는 PUT 없이도 살 수있었습니다. 그러나 클라이언트 개발자의 관점에서 볼 때 그의 삶은 훨씬 단순 해졌습니다.

PUT 이전에는 클라이언트가 서버가 생성 한 URL이나 서버가 생성 한 모든 URL 또는 서버로 전송할 데이터가 이미 업데이트되었는지 여부를 직접 알 수 없었습니다. PUT은 이러한 모든 두통을 완화시켜줍니다. PUT은 dem 등원이며 PUT은 경쟁 조건을 처리하며 PUT은 클라이언트가 URL을 선택할 수 있도록합니다.


3
당신의 짧은 대답은 매우 잘못되었을 수 있습니다. HTTP 프록시는 HTTP PUT을 자유롭게 반복 할 수 있습니다. 따라서 PUT이 실제로 SQL INSERT를 수행하는 경우 두 번째로 실패 할 수 있습니다. 즉, 다른 결과를 반환하므로 IDEMPOTENT (PUT과 POST의 차이)가
아닙니다.

36

Ruby on Rails 4.0은 PUT 대신 'PATCH'방법을 사용하여 부분 업데이트를 수행합니다.

RFC 5789는 PATCH에 대해 말합니다 (1995 년 이후).

상호 운용성을 개선하고 오류를 방지하려면 새로운 방법이 필요합니다. PUT 메소드는 이미 완전한 새 본문으로 자원을 겹쳐 쓰도록 정의되어 있으며 부분 변경을 위해 재사용 할 수 없습니다. 그렇지 않으면 프록시 및 캐시, 심지어 클라이언트 및 서버까지도 작업 결과가 혼란 스러울 수 있습니다. POST는 이미 사용되었지만 광범위한 상호 운용성이 없습니다 (하나의 경우 패치 형식 지원을 발견하는 표준 방법은 없습니다). PATCH는 이전 HTTP 사양에서 언급되었지만 완전히 정의되지 않았습니다.

" Edge Rails : PATCH는 업데이트를위한 새로운 기본 HTTP 방법입니다 "라고 설명합니다.


27

이미 언급 한 내용을 복구 할 위험이 있으므로 PUT 은 리소스를 생성 할 때 클라이언트가 URL의 끝을 제어한다는 것을 기억해야 합니다. 따라서 PUTPOST 중 하나를 선택 하는 것은 URL 스킴에 상관없이 정확하고 정규화 된 URL 을 제공하도록 클라이언트를 얼마나 신뢰할 수 있는지에 대한 것 입니다.

클라이언트가 올바른 작업을 수행 할 수 있다고 완전히 신뢰할 수없는 경우 POST 를 사용하여 새 항목을 만든 다음 응답으로 클라이언트에 URL을 다시 보내는 것이 더 적합합니다 .


2
나는 이것에 조금 늦었다. 그러나 다른 웹 사이트에서 비슷한 것을 말하는 누군가가 그것을 클릭하도록했다. 자원을 작성하고 자동 증가 ID를 사용자 지정 이름 대신 "식별자"로 사용하는 경우 POST 여야합니다.
Ixmatus

2
PUT은 응답이 아닌 한 정식 자원 이름 포함 된 Location헤더를 반환하는 한 정식이 아닌 이름으로 자원을 참조하여 자원을 작성할 수 있습니다 .
Ether

1
@Joshcodes는 동일한 기본 리소스를 참조하는 많은 URI를 가질 수 있다는 것을 잊지 마십시오. 그래서 에테르 말한 것은 사운드 조언 클라이언트는 URL에 PUT (즉, 같은 더 의미있을 수있다 PUT /X-files/series/4/episodes/max) 그 새 리소스에 짧은 정식 고유 링크 (즉, 제공하는 URI로 서버 응답 /X-Ffiles/episodes/91)
thecoshman

@thecoshman은 URL 구조가 클라이언트에 속하지 않는 문제입니다. 자체 발견 (REST의 일부)에 대해 읽으면이를 분명히하는 데 도움이 될 수 있습니다.
Joshcodes

그런 다음 @Joshcodes는 그 논리에 따라 클라이언트는 URL 제공에 신경 쓰지 않아야하므로 PUT을 사용하여 만들면 안됩니다. 클라이언트가 PUT에 URL을 제공하지 않으면 "PUT / comments / new"와 같이 서버가 "204 / comments / 234532"로 응답 할 수 있지만 약간은 나에게 RPC 클라이언트해야 단지 POST로 / 의견 ...
thecoshman

24

아주 간단한 방법으로 Facebook 타임 라인을 예로 들겠습니다.

사례 1 : 타임 라인에 무언가를 게시하면 새로운 항목입니다. 따라서이 경우 POST 메소드는 비등 전성이므로 POST 메소드를 사용합니다.

사례 2 : 친구가 처음으로 게시물에 댓글을 달면 데이터베이스에 POST 방법이 사용되도록 새 항목이 생성됩니다.

사례 3 : 친구가 자신의 댓글을 편집하면이 경우 댓글 ID가 있으므로 데이터베이스에 새 항목을 만드는 대신 기존 댓글을 업데이트합니다. 따라서이 유형의 조작에는 PUT 메소드가 dem 등원이므로 사용하십시오. *

한 줄로 POST 를 사용 하여 데이터베이스에 새 항목 을 추가 하고 PUT사용 하여 데이터베이스에서 무언가 를 업데이트 하십시오.


4
주석이 사용자 ID, 작성된 날짜, 주석 메시지 등의 특성을 가진 오브젝트이고 편집시 주석 메시지 만 업데이트되는 경우 여기에서 PATCH를 수행해야합니까?
Habeeb Perwad

기존 리소스가 업데이트되고 있기 때문에 FUT에서 주석을 업데이트하는 데 PUT이 사용되며 이는 PUT이 수행하는 작업 (리소스 업데이트)입니다. POST와 달리 PUT은 dem 등식입니다. dem 등원 인 HTTP 동사는 오류 처리에 영향을 주지만 사용법을 지시하지는 않습니다. 보다 자세한 설명은 내 대답을 참조하십시오. stackoverflow.com/questions/630453/put-vs-post-in-rest/…
Joshcodes

21

가장 중요한 고려 사항은 신뢰성 입니다. POST 메시지가 유실되면 시스템 상태가 정의되지 않습니다. 자동 복구가 불가능합니다. PUT 메시지의 경우, 첫 번째 재 시도까지만 상태가 정의되지 않습니다.

예를 들어 POST로 신용 카드 거래를 생성하는 것은 좋지 않을 수 있습니다.

자원에 자동 생성 된 URI가있는 경우 생성 된 URI (빈 자원을 가리키는)를 클라이언트에 전달하여 PUT을 계속 사용할 수 있습니다.

다른 고려 사항 :

  • POST는 전체 포함 리소스의 캐시 된 복사본을 무효화합니다 (일관성 향상)
  • POST 응답이있는 동안 PUT 응답을 캐시 할 수 없습니다 (컨텐츠 위치 및 만료 필요)
  • PUT은 Java ME, 구형 브라우저, 방화벽 등에서 덜 지원됩니다.

이것은 올바르지 않습니다. POST의 경우, 상태는 정의되어 있지 않습니다 최초의 성공적인 재 시도까지. 그런 다음 서버가 POST를 수락 (메시지 도착하지 않음)하거나 중복 ID (메시지 도착, 응답이 유실 됨) 또는 다른 유효한 응답에 대해 409 충돌을 발생시킵니다.
Joshcodes

일반적으로 사용자 작업은 POST 작업이 두 작업이 하나의 효과와 동일한 효과를 보장 할 수 없기 때문에 POST 작업을 안전하게 다시 시도 할 수 없습니다. "ID"라는 용어는 HTTP와 관련이 없습니다. URI는 리소스를 식별합니다.
Hans Malherbe

사용자 에이전트는 POST 작업을 원하는 횟수만큼 "안전하게"재 시도 할 수 있습니다. 중복 ID 오류 ( 자원에 ID가 있다고 가정 ) 또는 중복 데이터 오류 (문제가 있고 자원에 ID가 없다고 가정 )를 수신합니다.
Joshcodes

벽에 머리를 강타. HTTP는 신뢰성 문제에 대한 해결책이 없으며, 이것은 잘 이해되지 않았고, 많이 논의되지 않았으며, 대다수의 웹 응용 프로그램에서 제공되지 않습니다. @Joshcodes이 질문에 대한 답변이 있습니다. 나는 본질적으로 Hans에 동의합니다. 문제가 있습니다.
bbsimonbb

@bbsimonbb, HTTP에는 강력하고 잘 문서화 된 오류 응답 세트가 있습니다. 이 질문에 대한 나의 대답 ( stackoverflow.com/questions/630453/put-vs-post-in-rest/… )은 사양에 따라 http를 사용하여 일관성을 얻는 방법을 다룹니다.
Joshcodes

17

이 주제를 처음 접하는 독자 는해야 할 일 에 대한 끝없는 토론 과 경험에서 얻은 교훈 이없는 것에 대해 놀라게 될 것입니다. REST가 SOAP보다 "선호"된다는 사실은 경험을 통한 높은 수준의 학습이지만, 거기서부터 우리가 발전 했어야한다고 생각합니까? 로이의 논문은 2000 년에있었습니다. 우리는 무엇을 개발 했습니까? 재밌었 어? 통합하기 쉬웠습니까? 지원하기 위해? 스마트 폰 및 비정상적인 모바일 연결의 증가를 처리 할 수 ​​있습니까?

ME에 따르면 실제 네트워크는 신뢰할 수 없다. 타임 아웃을 요청합니다. 연결이 재설정됩니다. 한 번에 몇 시간 또는 며칠 동안 네트워크가 다운됩니다. 기차는 모바일 사용자와 함께 터널로 들어갑니다. 주어진 모든 요청에 ​​대해 (이 토론에서 때때로 인정되는 바와 같이) 요청은 도중에 물에 빠지거나 응답이 물에 빠질 수 있습니다. 이러한 상황에서 실질적인 자원에 대해 직접 PUT, POST 및 DELETE 요청을 발행하는 것은 항상 조금 잔인하고 순진합니다.

HTTP는 요청-응답의 안정적인 완료를 보장하기 위해 아무 것도하지 않으며, 이는 네트워크 인식 응용 프로그램의 작업이기 때문에 괜찮습니다. 이러한 응용 프로그램을 개발하면 POST 대신 PUT을 사용하도록 후프를 건너 뛰고 중복 요청을 감지하면 서버에서 특정 종류의 오류를 발생시키는 후프를 더 많이 사용할 수 있습니다. 클라이언트로 돌아가서 이러한 오류를 해석하고 다시 가져오고, 다시 확인하고 다시 게시하려면 후프를 뛰어 넘어야합니다.

또는 이렇게 할 수 있습니다 : 안전하지 않은 요청을 임시 단일 사용자 리소스로 간주하십시오 (작업이라고 함). 클라이언트는 자원에 빈 POST가있는 실질적인 자원에 대해 새로운 "조치"를 요청합니다. POST는이 용도로만 사용됩니다. 새로 작성된 작업의 URI를 안전하게 소유하면 클라이언트는 안전하지 않은 요청을 대상 자원이 아닌 작업 URI에 PUT합니다 . 조치를 해결하고 "실제"자원을 업데이트하는 것은 API의 역할이며, 신뢰할 수없는 네트워크와 분리되어 있습니다.

서버는 비즈니스를 수행하고 응답을 리턴 하며 동의 된 조치 URI에 대해 응답 을 저장합니다 . 문제가 발생하면 클라이언트는 요청을 반복하고 (자연스러운 행동!) 서버가 이미 요청을 보았을 경우 저장된 응답을 반복하고 다른 작업은 수행하지 않습니다 .

약속을 통해 유사점을 신속하게 파악할 수 있습니다. 어떤 작업을 수행하기 전에 결과에 대한 자리 표시자를 만들고 반환합니다. 약속과 마찬가지로 동작은 한 번만 성공하거나 실패 할 수 있지만 결과는 반복적으로 가져올 수 있습니다.

무엇보다도, 우리는 송수신 애플리케이션에 고유하게 식별 된 작업을 해당 환경의 고유성과 연결할 수있는 기회를 제공합니다. 또한 고객의 책임있는 행동을 요구하고 시행 할 수 있습니다. 요청을 원하는만큼 반복하지만 기존 결과의 결정적인 결과를 얻을 때까지 새로운 조치를 취하지 마십시오.

따라서 수많은 가시적 인 문제가 사라집니다. 반복되는 삽입 요청은 중복을 생성하지 않으며 데이터를 소유 할 때까지 실제 리소스를 생성하지 않습니다. (데이터베이스 열은 널 입력 가능하지 않을 수 있습니다). 반복되는 업데이트 요청은 호환되지 않는 상태가되지 않으며 이후 변경 사항을 덮어 쓰지 않습니다. 고객은 어떤 이유로 든 (클라이언트 충돌, 응답 누락 등) 원래 확인을 (다시) 가져오고 완벽하게 처리 할 수 ​​있습니다.

연속 삭제 요청은 404 오류를 발생시키지 않고 원래 확인을보고 처리 할 수 ​​있습니다. 예상보다 시간이 오래 걸리면 임시로 응답 할 수 있으며 고객이 최종 결과를 다시 확인할 수있는 장소가 있습니다. 이 패턴의 가장 좋은 부분은 Kung-Fu (Panda) 속성입니다. 클라이언트가 요청 언제든지 그들이 응답을 이해하고,로 돌려없는 반복을 위해 우리는 성향을 약점을 강도를 :-)

이것이 RESTful이 아니라고 말하기 전에 REST 원칙을 존중하는 다양한 방법을 고려하십시오. 클라이언트는 URL을 구성하지 않습니다. 의미에 약간의 변화가 있지만 API는 검색 가능한 상태를 유지합니다. HTTP 동사가 적절하게 사용됩니다. 이것이 구현에 큰 변화라고 생각한다면 경험이 아니라고 말할 수 있습니다.

저장할 대량의 데이터가 있다고 생각되면 볼륨을 말해 보겠습니다. 일반적인 업데이트 확인은 킬로바이트의 일부입니다. HTTP는 현재 결정적으로 응답하는 데 1-2 분을 제공합니다. 일주일 동안 만 작업을 저장하더라도 클라이언트는 따라 잡을 기회가 충분합니다. 볼륨이 매우 큰 경우 전용 산 호환 키 값 저장소 또는 인 메모리 솔루션이 필요할 수 있습니다.


1
응답 저장은 세션을 유지하는 것과 같지 않습니까? (수평) 스케일링 문제가 발생할 수 있습니다.
Saurabh Harwande

17

다른 사람들이 제안한 차이점 외에도 하나 더 추가하고 싶습니다.

POST 방법 에서는 본문 매개 변수를 보낼 수 있습니다form-data

PUT 방법 에서는 body params를 보내야합니다.x-www-form-urlencoded

헤더 Content-Type:application/x-www-form-urlencoded

이것에 따르면 PUT 방법으로 파일이나 멀티 파트 데이터를 보낼 수 없습니다

편집하다

"application / x-www-form-urlencoded"컨텐츠 유형은 많은 양의 이진 데이터 또는 ASCII가 아닌 문자를 포함하는 텍스트를 전송하는 데 비효율적입니다. 컨텐츠 유형 "multipart / form-data"는 파일, 비 ASCII 데이터 및 2 진 데이터를 포함하는 양식을 제출하는 데 사용해야합니다.

제출해야하는 경우

파일, 비 ASCII 데이터 및 이진 데이터

POST 방법을 사용해야 합니다


3
왜 이것이 공표되지 않았습니까? 사실이라면 이것이 중요한 차이가 아닌가?
Iofacture

2
사용자 프로필 사진 업로드를 포함하여 프로필 업데이트를 위해 API를 구현할 때 직면했습니다. 그런 다음 우편 배달부, Ajax, PHP curl 및 laravel 5.6을 백엔드로 테스트했습니다.
Rohit Dhiman

14

REST 서비스에 HTTP POST 대 HTTP PUT 메소드를 사용하는시기에 대해서는 항상 약간의 혼동이있는 것 같습니다. 대부분의 개발자는 CRUD 작업을 HTTP 메서드에 직접 연결하려고합니다. 나는 이것이 정확하지 않으며 CRUD 개념을 HTTP 메소드에 간단히 연관시킬 수는 없다고 주장 할 것이다. 그건:

Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE

CRUD 조작의 R (etrieve) 및 D (elete)는 각각 HTTP 메소드 GET 및 DELETE에 직접 맵핑 될 수 있습니다. 그러나 혼란은 C (reate) 및 U (update) 작업에 있습니다. 어떤 경우에는 작성에 PUT을 사용할 수 있지만 다른 경우에는 POST가 필요합니다. 모호성은 HTTP PUT 방법과 HTTP POST 방법의 정의에 있습니다.

HTTP 1.1 스펙에 따르면 GET, HEAD, DELETE 및 PUT 메소드는 dem 등원이어야하며 POST 메소드는 dem 등원이 아닙니다. 즉, 작업이 리소스에서 한 번 또는 여러 번 수행 될 수 있고 항상 해당 리소스의 동일한 상태를 반환하는 경우에는 dem 등원입니다. i 등원이 아닌 작업은 한 요청에서 다른 요청으로 리소스의 수정 된 상태를 반환 할 수 있습니다. 따라서 i 등원이 아닌 작업에서는 동일한 상태의 리소스를받을 것이라는 보장이 없습니다.

위의 dem 등원 정의에 따라 REST 서비스에 HTTP POST 메소드를 사용하는 것과 HTTP PUT 메소드를 사용하는 방법은 다음과 같습니다.

The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).

두 경우 모두 이러한 결과는 동일한 결과로 여러 번 수행 될 수 있습니다. 즉, 작업을 두 번 이상 요청하여 리소스가 변경되지 않습니다. 따라서 진정한 dem 등식 작업입니다. 다음과 같은 경우에 HTTP POST 메소드를 사용하십시오.

The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.

결론

REST 서비스의 CRUD 조작을 HTTP 메소드에 직접 연관시키고 맵핑하지 마십시오. HTTP PUT 방법과 HTTP POST 방법의 사용은 해당 작업의 dem 등원 측면을 기반으로해야합니다. 즉, 조작이 dem 등원 인 경우 HTTP PUT 메소드를 사용하십시오. 조작이 dem 등원이 아닌 경우 HTTP POST 메소드를 사용하십시오.


2
Update => HTTP POST : POST는 업데이트 용이 아닙니다
Premraj

@premraj 당신은 Burhan이 당신에게하지 말라고 가정했다; 즉, CRUD, REST 및 HTTP를 혼동하고 있습니다. 이러한 것들이 정의 된 RFC 7231을 읽으면 HTTP 프로토콜에서 POST의 정의가 확실히 업데이트를 허용한다는 것을 알 수 있습니다. 달리 말하면 REST의 제약 조건입니다.
IAM_AL_X

13

오리진 서버는 해당 URI로 자원을 작성할 수 있습니다.

따라서 POST를 사용하지만 리소스 생성에 필요하지는 않지만 PUT을 사용합니다. 둘 다 지원할 필요는 없습니다. 나를 위해 POST는 완벽하게 충분합니다. 따라서 디자인 결정입니다.

인용 한 바와 같이, IRI에 할당 된 자원이없는 경우 PUT을 사용하고 어쨌든 자원을 작성하려고합니다. 예를 들어 PUT /users/123/password일반적으로 이전 비밀번호를 새 비밀번호로 바꾸지 만 비밀번호가없는 경우 (예 : 새로 등록한 사용자 또는 금지 된 사용자를 복원하여) 비밀번호를 작성할 수 있습니다.


PUT 사용법에 대한 몇 가지 좋은 예 중 하나를 제공했다고 생각합니다.
thecoshman

12

다음과 같이 착륙하겠습니다.

PUT은 URI로 식별되는 리소스를 나타냅니다. 이 경우 업데이트 중입니다. 리소스를 언급하는 세 동사의 일부입니다. 삭제하고 다른 두 개를 얻으십시오.

POST는 기본적으로 자유 형식 메시지이며 그 의미는 '대역 외'로 정의됩니다. 메시지가 디렉토리에 자원을 추가하는 것으로 해석 될 수 있으면 괜찮을 것입니다. 그러나 기본적으로 자원에 어떤 일이 발생하는지 알기 위해 보내려는 (게시) 메시지를 이해해야합니다.


PUT 및 GET 및 DELETE는 자원을 참조하므로 정의 상으로는 dem 등원입니다.

POST는 다른 세 가지 기능을 수행 할 수 있지만 캐시 및 프록시와 같은 중개자에서 요청의 의미가 유실됩니다. 게시물의 URI가 적용되는 리소스를 반드시 나타내는 것은 아니기 때문에 리소스에 대한 보안 제공에도 적용됩니다 (그렇지만 가능).

PUT은 작성일 필요는 없습니다. 리소스가 아직 생성되지 않은 경우 서비스에서 오류가 발생할 수 있지만 그렇지 않으면 업데이트하십시오. 또는 그 반대의 경우도 리소스를 생성 할 수 있지만 업데이트는 허용하지 않습니다. PUT에 필요한 유일한 것은 특정 리소스를 가리키고 페이로드는 해당 리소스를 나타내는 것입니다. 성공적인 PUT은 GET이 동일한 자원을 검색한다는 것을 의미합니다 (방해 금지).


편집 : PUT을 만들 수있는 또 하나의 것이지만, 그렇다면 ID는 자연스러운 ID이어야합니다. 그렇게하면 두 번 PUT 할 때 두 번째 풋이 첫 번째 풋 업데이트입니다. 이것은 dem 등원이 됩니다.

ID가 생성되면 (예 : 새 직원 ID) 동일한 URL을 가진 두 번째 PUT이 새 레코드를 작성하여 dem 등원 규칙을 위반합니다. 이 경우 동사는 POST이고 메시지 (자원이 아님)는이 메시지에 정의 된 값을 사용하여 자원을 작성하는 것입니다.


9

의미는 "GET"과 같은 "PUT"이 dem 등원이어야한다는 의미에서 다릅니다. 즉, 동일한 정확한 PUT 요청을 여러 번 수행 할 수 있으며 결과는 한 번만 실행하는 것처럼됩니다.

가장 널리 사용되고 가장 유용한 규칙을 설명하겠습니다.

특정 URL에 리소스를 넣으면 해당 URL 또는 해당 줄에 저장해야합니다.

특정 URL의 리소스에 POST 할 때 관련 정보를 해당 URL에 게시하는 경우가 종종 있습니다. 이는 URL의 리소스가 이미 존재 함을 의미합니다.

예를 들어, 새 스트림을 만들려면 일부 URL에 넣을 수 있습니다. 그러나 기존 스트림에 메시지를 게시하려면 해당 URL에 POST하십시오.

스트림의 속성을 수정하는 경우 PUT 또는 POST로 수행 할 수 있습니다. 기본적으로 작업이 dem 등원 일 경우에만 "PUT"을 사용하십시오. 그렇지 않으면 POST를 사용하십시오.

그러나 모든 최신 브라우저가 GET 또는 POST 이외의 HTTP 동사를 지원하지는 않습니다.


POST를 설명하는 것은 실제로 PATCH의 작동 방식입니다. POST는 "메일 링리스트에 게시"에서와 같이 "추가"와 더 유사한 것을 의미합니다.
Alexander Torstling

8

대부분의 경우 다음과 같이 사용합니다.

  • 자원을 컬렉션에 게시
  • collection / : id로 식별 된 자원을 PUT

예를 들면 다음과 같습니다.

  • POST / 항목
  • PUT / items / 1234

두 경우 모두 요청 본문에는 만들거나 업데이트 할 리소스에 대한 데이터가 포함됩니다. 경로 이름에서 POST는 idempotent가 아니며 (3 번 호출하면 3 개의 객체가 생성됨) PUT은 idempotent입니다 (3 번 호출하면 결과는 동일 함). PUT은 종종 "upsert"작업 (만들기 또는 업데이트)에 사용되지만 수정에만 사용하려는 경우 항상 404 오류를 반환 할 수 있습니다.

POST는 컬렉션에서 새 요소를 "만들고"PUT은 주어진 URL에서 요소를 "바꾸"지만 부분 수정을 위해 PUT을 사용하는 것이 매우 일반적입니다. 즉, 기존 리소스를 업데이트 할 때만 사용합니다. 본문에 포함 된 필드 만 수정하십시오 (다른 필드는 무시). REST-purist가 되려면 PUT이 전체 리소스를 대체해야하며 부분 업데이트에 PATCH를 사용해야합니다. 모든 API 엔드 포인트에서 동작이 명확하고 일관성이있는 한 개인적으로 관심이 없습니다.

REST는 API를 단순하게 유지하기위한 일련의 규칙과 지침입니다. "RESTfull"상자를 체크하기 만하면 복잡한 해결 방법이 나오면 목적을 잃게됩니다.)


7

이것들을 설명 할 수있는 불가지론적인 방법이있을 수 있지만, 웹 사이트에 대한 답변에서부터 다양한 진술과 충돌하는 것 같습니다.

여기서 명확하고 직접합시다. Web API를 사용하는 .NET 개발자 인 경우 사실은 (Microsoft API 설명서에서) http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web입니다. -api-that-crus-operations :

1. PUT = UPDATE (/api/products/id)
2. MCSD Exams 2014 -  UPDATE = PUT, there are **NO** multiple answers for that question period.

물론 "POST"를 사용하여 업데이트 할 수는 있지만 주어진 프레임 워크에서 제시 한 규칙을 따르십시오. 제 경우에는 .NET / Web API이므로 PUT은 업데이트입니다. 토론이 없습니다.

Amazon 및 Sun / Java 웹 사이트 링크로 모든 의견을 읽는 모든 Microsoft 개발자에게 도움이되기를 바랍니다.


7

간단한 규칙은 다음과 같습니다.

URL에 대한 PUT 은 해당 URL에있는 자원을 업데이트하거나 작성하는 데 사용해야합니다.

URL에 대한 POST 는 다른 ( "하위") URL에 있거나 HTTP를 통해 찾을 수없는 자원을 업데이트하거나 작성하는 데 사용해야합니다.


1
PUT은 업데이트 용이 아니며 교체 용입니다. 만들려면 무언가로 바꾸지 마십시오. POST는 어떤 형태의 형태로도 업데이트되지 않습니다.
thecoshman

2
http 사양이 그렇게 말합니까? 아니면 다른 것에 대한 의견을 제시하고 있습니까?
Adam Griffiths

업데이트하는 것이 무엇인지 모르는 경우 업데이트하는 것이 상식입니다. POST는 새로운 리소스를 만들기위한 것입니다.
thecoshman

2
thecoshman (여기에서 의미론을 남용하고 있음)은 약간의 차이가있는 동일한 리소스 인 경우 대체가 업데이트가 될 수 있습니다. replace는 replace가 동일한 자원을 변경하는 데 사용되는 경우에만 유효합니다. 특히 새 자원에 고유 ID가없는 경우 새롭고 다른 자원으로 대체하는 것은 유효하지 않습니다 (이전을 제거하고 새로 추가 하시겠습니까?). POST, OTOH는 작성, 업데이트, 교체 및 삭제할 수있는 항목입니다. post를 사용하면 '할인 적용'과 같이 해석 할 메시지가 있는지 여부에 따라 달라집니다. 논리.
Gerard ONeill

두 번째 의견은 자원을 '얻고'필요한 필드를 수정 한 다음 다시 넣는 방법은 어떻습니까? 또는 리소스가 다른 소스에서 왔지만 자연 ID (외부 ID)를 사용하는 경우 어떻습니까? put은 원래 데이터가 변경 될 때 URL에서 리소스를 자연스럽게 업데이트합니다.
Gerard ONeill

6

데이터베이스 작업에 익숙하다면

  1. 고르다
  2. 끼워 넣다
  3. 최신 정보
  4. 지우다
  5. 병합 (이미 존재하는 경우 업데이트, 그렇지 않으면 삽입)

내가 사용 PUT운영 및 사용 등의 병합 및 업데이트를 POST삽입합니다.


5

실제로 POST는 리소스를 만드는 데 효과적입니다. 새로 작성된 자원의 URL은 위치 응답 헤더에 리턴되어야합니다. 리소스를 완전히 업데이트하려면 PUT을 사용해야합니다. RESTful API를 설계 할 때 모범 사례임을 이해하십시오. 이와 같이 HTTP 스펙은 자원 작성 / 업데이트에 대한 몇 가지 제한 사항으로 PUT / POST 사용을 제한하지 않습니다. 모범 사례를 요약 한 http://techoctave.com/c7/posts/71-twitter-rest-api-dissected 를 살펴보십시오 .


대부분의 경우,이 모든 소음을 읽음으로써 공에 보입니다. 그래도 PUT을 작성 / 업데이트 대신 replace 메소드로 참조해야합니다. 나는 그것이하는 일을 더 잘 설명한다고 생각합니다.
thecoshman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.