How to PATCH in HTTP APIs

How to PATCH in HTTP APIs

How to properly use PATCH HTTP method and how to patch JSON documents. JSON Patch and JSON Merge Patch.

7b2e4bf7ecca28e530e1c421f0676c0b?s=128

Honza Javorek

April 15, 2015
Tweet

Transcript

  1. PATCH & HTTP APIs

  2. Honza Python API design Apiary Pyvo {…} PR API Blueprint

    @honzajavorek honzajavorek.cz
  3. Modifying Resources { "type": "Mazda", "color": "red", "stolen": true }

    ! { "type": "Mazda", "color": "blue", "stolen": false }
  4. Web { "type": "Mazda", "color": "red", "stolen": true } !

    { "type": "Mazda", "color": "blue", "stolen": false }
  5. API { "type": "Mazda", "color": "red", "stolen": true } !

    { "type": "Mazda", "color": "blue", "stolen": false } PUT /car
  6. Has flaws vs. Good enough • Needs recent GET on

    the resource. • Even with recent GET , there's obviously still race condition. • We need to send the whole resource (bandwidth). • But come on, we do this all the time with web forms…
  7. Partial Update aka PATCH

  8. PATCH • New HTTP method for partial updates (RFC 5789)

    • Body contains a description of changes. • The changes must be applied atomically by server.
  9. Content-Type: my-favorite-diff-format some diff instructions PATCH /car Content-Type: application/json {

    "type": "Mazda", "color": "blue", "stolen": false } 200
  10. Content-Type: application/json { "color": "blue", "stolen": false } PATCH /car

    Content-Type: application/json { "type": "Mazda", "color": "blue", "stolen": false } 200
  11. Content-Type: application/json { "color": "blue", "stolen": false } PATCH /car

    Content-Type: application/json { "type": "Mazda", "color": "blue", "stolen": false } 200
  12. application/json • Does not actually say anything about the diff

    format. • No shared libraries. • It is ambiguous: delete property vs. set to null? • You meet limits very soon: adding to arrays?
  13. JSON Patch

  14. JSON Patch • JavaScript Object Notation Patch (RFC 6902) •

    Way to describe changes made on JSON. • Not ambiguous, supports addressing nested structures (e.g. replacing properties of nested objects, adding to array). • application/json-patch+json
  15. Content-Type: application/json-patch+json [ {"op": "replace", "path": "/color", "value": "blue"}, {"op":

    "replace", "path": "/stolen", "value": false} ] PATCH /car Content-Type: application/json { "type": "Mazda", "color": "blue", "stolen": false } 200
  16. JSON Patch • atomic operations • path is able to

    address any element in JSON document • RFC is very short and half of it are examples. Just read it. • libraries…
  17. • JSON Pointer (RFC 6901) • Easy to address any

    part of JSON document • "/pets/0" (first element in array pets) What "path"?
  18. • test: check if path has given value (if not,

    the patch fails) • remove: remove path • add: insert new value at path • replace: replace value at path • move: remove + add • copy: clones node inside the document Operations
  19. None
  20. Content-Type: application/json { "color": "blue", "stolen": false } PATCH /car

    Content-Type: application/json { "type": "Mazda", "color": "blue", "stolen": false } 200
  21. JSON Merge Patch

  22. JSON Merge Patch • RFC 7396 • Way to describe

    changes made on JSON. • Not ambiguous, supports addressing nested structures (e.g. replacing properties of nested objects). Replaces arrays. • application/merge-patch+json
  23. Content-Type: application/merge-patch+json { "color": "blue", "stolen": false } PATCH /car

    Content-Type: application/json { "type": "Mazda", "color": "blue", "stolen": false } 200
  24. JSON Merge Patch • standardization & exact spec of what

    everyone already does • very young • some libraries… • supported by orchestrate.io
  25. None
  26. Misc Tricks • Return "Undo Patch" in response (or link

    it) to provide undo. • Conditional requests can prevent race conditions: • use If-Match headers & 412 HTTP status • PUT/PATCH exposes whole document: • use JSON Schema & 400/422 for access control
  27. More • RFCs: 1855, 6902, 5789, 7396, 6901, 7230-7237, …

    • Misc: • http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/ • https://github.com/apicraft/detroit2013/wiki/PATCH-and-partial-updates • https://www.mnot.net/blog/2012/09/05/patch • http://jsonpatch.com/ • http://slides.com/warpech/introduction-to-json-patch#/