2. PATCH 方法 (The PATCH Method)
2. PATCH 方法 (The PATCH Method)
PATCH 方法请求将请求实体 (request entity) 中描述的一组更改应用到由 Request-URI 标识的资源上. 这组更改以称为 "补丁文档 (patch document)" 的格式表示, 由媒体类型 (media type) 标识. 如果 Request-URI 未指向现有资源, 服务器可以 (MAY) 创建新资源, 这取决于补丁文档类型 (是否可以逻辑上修改空资源) 和权限等因素.
PUT 和 PATCH 请求之间的差异体现在服务器处理所包含实体以修改由 Request-URI 标识的资源的方式上. 在 PUT 请求中, 所包含的实体被视为存储在源服务器 (origin server) 上的资源的修改版本, 客户端请求替换已存储的版本. 然而, 对于 PATCH, 所包含的实体包含一组指令 (instructions), 描述如何修改当前驻留在源服务器上的资源以生成新版本. PATCH 方法影响由 Request-URI 标识的资源, 它也可能 (MAY) 对其他资源产生副作用 (side effects); 即, 通过应用 PATCH 可能会创建新资源或修改现有资源.
根据 [RFC2616] 第 9.1 节的定义, PATCH 既不是安全的 (safe) 也不是幂等的 (idempotent).
可以以幂等的方式发出 PATCH 请求, 这也有助于防止在相近时间范围内对同一资源的两个 PATCH 请求发生冲突 (collisions) 而产生不良后果. 来自多个 PATCH 请求的冲突可能比 PUT 冲突更危险, 因为某些补丁格式需要从已知的基点 (base-point) 操作, 否则它们会破坏资源. 使用这种补丁应用程序的客户端应该 (SHOULD) 使用条件请求 (conditional request), 以便在资源自客户端上次访问后已被更新时请求将失败. 例如, 客户端可以在 PATCH 请求的 If-Match 头中使用强 ETag [RFC2616].
也存在一些补丁格式不需要从已知基点操作的情况 (例如, 向日志文件追加文本行, 或向数据库表添加非冲突行), 在这种情况下, 客户端请求中不需要同样的谨慎.
服务器必须 (MUST) 原子地 (atomically) 应用整个更改集, 并且永远不能提供 (例如, 在此操作期间响应 GET) 部分修改的表示 (representation). 如果无法成功应用整个补丁文档, 则服务器不得 (MUST NOT) 应用任何更改. 成功 PATCH 的确定可能会因补丁文档和被修改资源的类型而异. 例如, 常见的 'diff' 实用程序可以生成适用于目录层次结构中多个文件的补丁文档. 原子性要求适用于受补丁影响的所有文件, 而不仅仅是其中一个. 有关状态码和可能的错误条件的详细信息, 请参见 "错误处理 (Error Handling)", 第 2.2 节.
如果请求通过缓存并且 Request-URI 标识一个或多个当前缓存的实体, 则这些条目应该 (SHOULD) 被视为陈旧的 (stale). 对此方法的响应只有在包含明确的新鲜度信息 (freshness information) (例如 Expires 头或 "Cache-Control: max-age" 指令) 以及与 Request-URI 匹配的 Content-Location 头时才可缓存 (cacheable), 表明 PATCH 响应主体是资源表示. 缓存的 PATCH 响应只能用于响应后续的 GET 和 HEAD 请求; 它不得 (MUST NOT) 用于响应其他方法 (例如 PATCH).
请注意, 请求中包含的实体头 (entity-headers) 仅适用于所包含的补丁文档, 不得 (MUST NOT) 应用于被修改的资源. 因此, Content-Language 头可能出现在请求中, 但它只意味着 (无论有什么价值) 补丁文档具有语言. 服务器不应 (SHOULD NOT) 存储此类头, 除非作为跟踪信息 (trace information), 并且不应 (SHOULD NOT) 以与 PUT 请求中可能使用它们的相同方式使用此类头值. 因此, 本文档未指定通过头修改文档的 Content-Type 或 Content-Language 值的方法, 尽管可以设计一种机制通过补丁文档来实现此目标.
不能保证可以使用 PATCH 修改资源. 此外, 预计不同的补丁文档格式将适用于不同类型的资源, 并且没有单一格式适用于所有类型的资源. 因此, 没有实现需要支持的单一默认补丁文档格式. 服务器必须 (MUST) 确保接收到的补丁文档适合目标 Request-URI 标识的资源类型.
客户端需要选择何时使用 PATCH 而不是 PUT. 例如, 如果补丁文档大小大于 PUT 中使用的新资源数据的大小, 那么使用 PUT 而不是 PATCH 可能更有意义. 与 POST 的比较更加困难, 因为 POST 以各种各样的方式使用, 并且如果服务器选择, 可以包含类似 PUT 和 PATCH 的操作. 如果操作不以可预测的方式修改由 Request-URI 标识的资源, 则应考虑使用 POST 而不是 PATCH 或 PUT.