--- title: "#19.5 HTTP method 共同研究會 - PUT 上集" tags: Meetups date: 2022-04-28 --- # PUT See [RFC-7231 PUT](https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.4) ------------- ## 4.3.4 PUT ### Definition定義 The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload. A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response. PUT 請求會根據 representation 的 payload 創建或取代目標資源的狀態。建議 PUT 的 payload(representation)跟 GET 拿的 body(representation)相同。 ### Side affect However, there is no guarantee that such a state change will be observable, since the target resource might be acted upon by other user agents in parallel, or might be subject to dynamic processing by the origin server, before any subsequent GET is received. A successful response only implies that the user agent's intent was achieved at the time of its processing by the origin server. 因兩次請求的狀態無法保證一致,當 PUT 成功回應時只代表 UA 的意圖在當下由來源伺服器處理完成了。 ### 目標資源不存在或已存在的Response If the target resource does not have a current representation and the PUT successfully creates one, then the origin server MUST inform the user agent by sending a 201 (Created) response. If the target resource does have a current representation and that representation is successfully modified in accordance with the state of the enclosed representation, then the origin server MUST send either a 200 (OK) or a 204 (No Content) response to indicate successful completion of the request. 如果目標資源不存在且 PUT 成功建立一個新的,來源伺服器**必須**回 201 如果目標資源存在且根據 payload 成功修改,來源伺服器**必須**回傳 200 或 204 代表成功完成請求 [RFC7231_201_Created](https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.2) [RFC7231_204_NoContent](https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.5) ### Don't do that An origin server SHOULD ignore unrecognized header fields received in a PUT request (i.e., do not save them as part of the resource state). 來源伺服器**應該**忽略 PUT 請求裡無法識別的 header 欄位。(即,不要把這些內容存到資源裡) ### 目標資源的約束 An origin server SHOULD verify that the PUT representation is consistent with any constraints the server has for the target resource that cannot or will not be changed by the PUT. This is particularly important when the origin server uses internal configuration information related to the URI in order to set the values for representation metadata on GET responses. When a PUT representation is inconsistent with the target resource, the origin server SHOULD either make them consistent, by transforming the representation or changing the resource configuration, or respond with an appropriate error message containing sufficient information to explain why the representation is unsuitable. The 409 (Conflict) or 415 (Unsupported Media Type) status codes are suggested, with the latter being specific to constraints on Content-Type values. 來源伺服器應該驗證 PUT 請求與目標資源的約束是否一致,這個約束不能或不會被 PUT 改變。 當不一致時,來源伺服器應該要想辦法讓它們一致,或是回應帶有足夠訊息的錯誤訊息,以解釋不合適的原因。 建議使用 409 或 415,其中 415 適用在 Content-Type 的約束 For example, if the target resource is configured to always have a Content-Type of "text/html" and the representation being PUT has a Content-Type of "image/jpeg", the origin server ought to do one of: a. reconfigure the target resource to reflect the new media type; 重新設定新的 media type b. transform the PUT representation to a format consistent with that of the resource before saving it as the new resource state; or, c. reject the request with a 415 (Unsupported Media Type) response indicating that the target resource is limited to "text/html", perhaps including a link to a different resource that would be a suitable target for the new representation. ### 我幾乎什麼都沒定義喔0.< HTTP does not define exactly how a PUT method affects the state of an origin server beyond what can be expressed by the intent of the user agent request and the semantics of the origin server response. It does not define what a resource might be, in any sense of that word, beyond the interface provided via HTTP. It does not define how resource state is "stored", nor how such storage might change as a result of a change in resource state, nor how the origin server translates resource state into representations. Generally speaking, all implementation details behind the resource interface are intentionally hidden by the server. An origin server MUST NOT send a validator header field (Section 7.2), such as an ETag or Last-Modified field, in a successful response to PUT unless the request's representation data was saved without any transformation applied to the body (i.e., the resource's new representation data is identical to the representation data received in the PUT request) and the validator field value reflects the new representation. This requirement allows a user agent to know when the representation body it has in memory remains current as a result of the PUT, thus not in need of being retrieved again from the origin server, and that the new validator(s) received in the response can be used for future conditional requests in order to prevent accidental overwrites (Section 5.2). [If-None-Match for PUT 看說明, 更新丟失問題](https://runebook.dev/zh-CN/docs/http/headers/if-none-match) ### PUT v.s. POST The fundamental difference between the POST and PUT methods is highlighted by the different intent for the enclosed representation. The target resource in a POST request is intended to handle the enclosed representation according to the resource's own semantics, whereas the enclosed representation in a PUT request is defined as replacing the state of the target resource. Hence, the intent of PUT is idempotent and visible to intermediaries, even though the exact effect is only known by the origin server. Proper interpretation of a PUT request presumes that the user agent knows which target resource is desired. A service that selects a proper URI on behalf of the client, after receiving a state-changing request, SHOULD be implemented using the POST method rather than PUT. If the origin server will not make the requested PUT state change to the target resource and instead wishes to have it applied to a different resource, such as when the resource has been moved to a different URI, then the origin server MUST send an appropriate 3xx (Redirection) response; the user agent MAY then make its own decision regarding whether or not to redirect the request. A PUT request applied to the target resource can have side effects on other resources. For example, an article might have a URI for identifying "the current version" (a resource) that is separate from the URIs identifying each particular version (different resources that at one point shared the same state as the current version resource). A successful PUT request on "the current version" URI might therefore create a new version resource in addition to changing the state of the target resource, and might also cause links to be added between the related resources. An origin server that allows PUT on a given target resource MUST send a 400 (Bad Request) response to a PUT request that contains a Content-Range header field (Section 4.2 of [RFC7233]), since the payload is likely to be partial content that has been mistakenly PUT as a full representation. Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource, or by using a different method that has been specifically defined for partial updates (for example, the PATCH method defined in [RFC5789]). ### Not Cacheable Responses to the PUT method are not cacheable. If a successful PUT request passes through a cache that has one or more stored responses for the effective request URI, those stored responses will be invalidated (see Section 4.4 of [RFC7234]). [RFC7231_409_Conflict](https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.8) [RFC7231_415_UnsupportedMediaType](https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.13) [RFC7231_Representation_Metadata](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1)