title: REST API Design - add / remove an item in an array field of a resource
body: <p>Let's assume we have the following REST resource collection endpoint:</p>
  <pre><code>/products
  </code></pre>
  <p>The resource looks like this:</p>
  <pre><code>GET /products/123
  Accept: application/json
  
  {
      &quot;id&quot;: &quot;123&quot;,
      &quot;name&quot;: &quot;Shampoo&quot;,
      ...
      &quot;ingredients&quot;: [
          &quot;Sodium Lauryl Sulfate&quot;,
          &quot;Sodium Laureth Sulfate&quot;,
          &quot;Hydrochloric Acid&quot;,
          ...
      ]
  }
  </code></pre>
  <p>Now, let's say I want to update the resource, and add or remove an ingredient to / from the <em>ingredients</em> field.
  One way is to <code>GET</code> the resource, manipulate the array, and <code>PUT</code> or <code>PATCH</code> back. However, this is pretty chatty protocol, and it also poses scaleability problem, if the array is too big.</p>
  <p>What is the best way to achieve this add / remove operation without having the source array?</p>
  <p>I already explored the following: <a href="https://www.rfc-editor.org/rfc/rfc6902" rel="nofollow noreferrer">JSON Patch Specification</a>
  But it seems the spec is not REST. It uses the same resource with different &quot;operation&quot; like representation, which is entirely different from the resource's representation.</p>
  <p>I would like to keep as much as possible the same representation of resource for <code>PUT</code> / <code>PATCH</code> method as it is appearing in <code>GET</code>.</p>
  <p>Here are my thoughts on the matter.</p>
  <ol>
  <li>Change the <em>string</em> type item to <em>object</em></li>
  <li>Add meta field to the object called <em>$op</em></li>
  </ol>
  <p>So in this design, here is how the resource looks like on <code>GET</code></p>
  <pre><code>GET /products/123
  Accept: application/json
  
  {
      &quot;id&quot;: &quot;123&quot;,
      &quot;name&quot;: &quot;Shampoo&quot;,
      ...
      &quot;ingredients&quot;: [
          {
              &quot;name&quot;: &quot;Sodium Lauryl Sulfate&quot;
          },
          {
              &quot;name&quot;: &quot;Sodium Laureth Sulfate&quot;
          },
          {
              &quot;name&quot;: &quot;Hydrochloric Acid&quot;
          },
          ...
      ]
  }
  </code></pre>
  <p>And now if I want to remove an item from the <em>ingredients</em> array:</p>
  <pre><code>PATCH /products/123
  Content-Type: application/json
  Accept: application/json
  
  {
      &quot;ingredients&quot;: [
          {
              &quot;$op&quot;: &quot;remove&quot;,
              &quot;name&quot;: &quot;Hydrochloric Acid&quot;
          }
      ]
  }
  </code></pre>
  <p>Or add it back:</p>
  <pre><code>PATCH /products/123
  Content-Type: application/json
  Accept: application/json
  
  {
      &quot;ingredients&quot;: [
          {
              &quot;$op&quot;: &quot;add&quot;,
              &quot;name&quot;: &quot;Hydrochloric Acid&quot;
          }
      ]
  }
  </code></pre>
  <p>Does anyone has a better way? Is there some standard on the subject?</p>