← API

HTTP PATCH Using Merge Patch

Context and Problem Statement

As our consumer api has expanded, one question that has come up more recently is if (and how) we should use the HTTP PATCH verb. The goal of this decision record is to determine if we should allow the usage of PATCHes in our API and, if so, standardized how they are formatted and used.

Decision Drivers

  • Consistency for API developers
  • Consistency and usability for API consumers

Decision Outcome

Considered Options

Pros and Cons of the Options

Allow HTTP PATCH and standardize on the JSON Merge Patch format

Pros

  • We already have working PATCH requests in production that are JSON Merge Patch compliant
  • Clients do not have to worry about submitting the whole entity model in use cases where it is not needed
  • Clients do not have to worry about out of band changes to fields not being updated. This mostly effects entity models which have eventual consistency.

Cons

  • There have been issues with client libraries not supporting PATCH in the past
  • Some argue PATCH is less RESTFUL
  • PATCH requests specifying computed fields may create ambiguity on the expected behavior
  • PATCH requests submitted simultaneously by multiple consumers against the same resource may create conflicts with ambiguous resolutions
  • PATCH is less commonly used

Allow HTTP PATCH and standardize on the JSON Merge Patch with additional restrictions

This option describes using JSON Merge Patch as the governing format for PATCH request, but includes additional restrictions on these types of requests that are not described in the RFC:

  1. PATCH requests MUST include a strong ETag. These are described as OPTIONAL in Section 2 of the PATCH RFC, but would be REQUIRED in the Banno API.
  2. PATCH requests MUST NOT include any complex fields, including computed and internal status fields.

Pros

  • We already have working PATCH requests in production that are JSON Merge Patch compliant
  • Clients do not have to worry about submitting the whole entity model in use cases where it is not needed
  • Clients do not have to worry about out of band changes to fields not being updated. This mostly effects entity models which have eventual consistency.
  • Unpredictable modifications due to conflicting requests cannot occur
  • Unpredictable behavior due to requests to modify complex fields cannot occur

Cons

  • There have been issues with client libraries not supporting PATCH in the past
  • Some argue PATCH is less RESTFUL
  • Complexity for the consumers around sending PATCH requests with valid ETag headers
  • Complexity for the developers when designing endpoints by forcing the identification of fields that are valid for modification through PATCH requests
  • PATCH is less commonly used

Disallow PATCH requests

Pros

  • Simplifies the API to use only the most common HTTP verbs
  • Requests that would be targeted by the PATCH verb would instead be placed within well-understood “intent” resources which are specific for targeted resource or, alternatively, to PUT endpoints which are more commonly found.

Cons

  • The number of intent endpoints to perform simple CRUD operations would proliferate throughout the API
  • The existing PATCH endpoints would need to be removed and replaced
  • PUT endpoints may be used instead, forcing clients to send the entire resource for every change. PUT endpoints may suffer from conflicts and modification of complex fields as well.