← Todos los artículos

JSON Patch vs JSON Merge Patch: RFC 6902 vs 7396

JSON Patch (RFC 6902) envía operaciones explícitas; JSON Merge Patch (RFC 7396) superpone un objeto parcial. Compara ambos con ejemplos y elige el correcto.

Cuando una API HTTP necesita actualizar parte de un recurso, dos estándares IETF compiten por la tarea: JSON Merge Patch (RFC 7396) y JSON Patch (RFC 6902). Se ven similares pero funcionan muy distinto —— Merge Patch superpone un objeto parcial, mientras que JSON Patch envía una lista explícita de operaciones. Esta guía muestra cómo funciona cada uno, los compara cabeza a cabeza y te ayuda a elegir el correcto.

El problema: actualizaciones parciales

Un request PUT reemplaza un recurso entero, lo que es derrochador y arriesgado cuando solo quieres cambiar un campo. El método HTTP PATCH existe para actualizaciones parciales —— pero PATCH no define un formato de body. Eso es lo que estos dos estándares proveen.

JSON Merge Patch (RFC 7396)

Un Merge Patch es simplemente una versión parcial del documento de destino. El servidor lo superpone: las keys del patch se establecen, las keys puestas a null se eliminan, y las keys no mencionadas se dejan tal cual.

// Original
{ "title": "Hello", "author": "Ada", "tags": ["a", "b"], "draft": true }

// Merge Patch body (Content-Type: application/merge-patch+json)
{ "title": "Hello World", "draft": null }

// Resultado
{ "title": "Hello World", "author": "Ada", "tags": ["a", "b"] }
//   ^ title actualizado    ^ author intacto         ^ draft eliminado (estaba null)

Es intuitivo y compacto. La trampa: como null significa «eliminar», no puedes usar Merge Patch para poner un valor a null, y los arrays solo se pueden reemplazar enteros —— no hay forma de cambiar un solo elemento de array.

JSON Patch (RFC 6902)

Un JSON Patch es un array ordenado de operaciones, cada una apuntando a una ubicación con una ruta JSON Pointer. Es explícito y preciso:

// JSON Patch body (Content-Type: application/json-patch+json)
[
  { "op": "replace", "path": "/title", "value": "Hello World" },
  { "op": "remove",  "path": "/draft" },
  { "op": "add",     "path": "/tags/-", "value": "c" },
  { "op": "test",    "path": "/author", "value": "Ada" }
]

Las seis operaciones:

opEfecto
addAñadir un valor (o append a un array con /-)
removeEliminar el valor en una ruta
replaceReemplazar el valor en una ruta
moveMover un valor de una ruta a otra
copyCopiar un valor a otra ruta
testAseverar un valor (abortar todo el patch si falla)

La op test habilita actualizaciones seguras y atómicas: si el documento no está en el estado esperado, todo el patch se rechaza —— útil para control de concurrencia optimista.

Comparación cabeza a cabeza

JSON Merge PatchJSON Patch
RFC73966902
Content-Typeapplication/merge-patch+jsonapplication/json-patch+json
LegibilidadAlta —— se ve como los datosMenor —— lista de operaciones
Puede poner un valor a nullNo (null significa eliminar)
Modificar un único elemento de arrayNo (reemplazar array entero)Sí (por índice)
Actualizaciones condicionales / atómicasNoSí (op test)
Move / copyNo
Mejor paraActualizaciones simples de campos de objetoEdiciones precisas, conscientes de arrays, atómicas

Cuándo usar cuál

  • JSON Merge Patch —— cuando los clientes actualizan sobre todo campos de objeto de nivel superior y valoras un body que se lee como el recurso. Excelente para ajustes simples y actualizaciones de perfil. Solo recuerda que no puedes poner campos a null ni editar items de array.
  • JSON Patch —— cuando necesitas editar elementos de array, mover o copiar valores, poner campos a null, o aplicar cambios atómicamente con una precondición. La elección estándar para edición colaborativa y change sets amigables con auditoría.

Semántica de HTTP PATCH: idempotencia y headers

Dos detalles HTTP que suelen pillar a equipos que envían un endpoint PATCH:

  • PATCH no está obligado a ser idempotente (a diferencia de PUT). Un JSON Patch con {"op":"add","path":"/items/-","value":...} hace append —— aplicarlo dos veces añade dos veces. Si quieres reintentos seguros, o bien usa una op test para aseverar el estado primero, o diseña tus ops para que la re-aplicación sea no-op (usa replace en una ruta fija en vez de add a /items/-).
  • Usa el Content-Type correcto. RFC 6902 = application/json-patch+json; RFC 7396 = application/merge-patch+json. Los servidores normalmente ramifican por esto.
  • Concurrencia optimista. Combina una op test de JSON Patch (o un header If-Match con ETag) para que escritores concurrentes no puedan sobrescribirse silenciosamente.

Librerías que vale la pena conocer

Para JSON Patch, fast-json-patch es el paquete npm de facto —— aplica, genera (diff de dos documentos para producir un patch) y observa (rastrea cambios a un objeto observado). Para JSON Merge Patch, las reglas son lo bastante pequeñas como para escribirlas inline, pero json-merge-patch las implementa con los casos límite de eliminación con null manejados.

Aplicando patches en código

// JavaScript —— fast-json-patch implementa RFC 6902
import { applyPatch } from 'fast-json-patch';
const updated = applyPatch(document, patchOps).newDocument;

// JSON Merge Patch es trivial de aplicar por recursión, pero una librería
// (p. ej. json-merge-patch) maneja las reglas de eliminación con null correctamente.

Después de aplicar un patch, puedes confirmar que el cambio es exactamente lo que pretendías diffeando antes y después —— ver Cómo comparar dos archivos JSON o pegar ambos en JSON Diff.

Preguntas frecuentes

¿Cuál es la diferencia entre JSON Patch y JSON Merge Patch?

JSON Merge Patch (RFC 7396) es una copia parcial del documento donde null elimina una key. JSON Patch (RFC 6902) es un array explícito de operaciones (add, remove, replace, move, copy, test) que apunta a rutas JSON Pointer. Merge Patch es más simple; JSON Patch es más potente.

¿Por qué JSON Merge Patch no puede poner un campo a null?

Porque en Merge Patch null es la señal para eliminar una key. Si necesitas guardar un valor null real, usa JSON Patch con una op replace.

¿Qué Content-Type debo usar?

application/merge-patch+json para Merge Patch y application/json-patch+json para JSON Patch, ambos enviados con el método HTTP PATCH.

¿Cómo edito un elemento de un array?

Usa JSON Patch con una ruta como /items/2, o append con /items/-. Merge Patch solo puede reemplazar el array entero.

Herramientas y lecturas relacionadas