Saltar al contenido
JSONCraft

Fundamentos

JSON Pointer y JSON Patch: ejemplo completo y rutas escapadas

Aprende a copiar una ruta JSON Pointer y aplicar las seis operaciones JSON Patch con un documento inicial y un resultado reproducible.

JSON Pointer identifica un valor por su ruta. JSON Patch describe una secuencia de cambios y utiliza esas rutas. No son lo mismo que JSONPath, que permite seleccionar conjuntos de valores mediante consultas.

Prueba el mismo documento en el visualizador

Abre el visualizador JSON, pulsa Ejemplo y selecciona un nodo. Copiar Pointer devuelve la ruta, mientras que Copiar valor JSON devuelve su contenido. El grafo representa una vista limitada; las copias conservan el valor completo.

Documento inicial:

{
  "users": [
    {
      "id": 1,
      "name": "Ana"
    },
    {
      "id": 2,
      "name": "Ben"
    }
  ],
  "a/b~c": {
    "": "value"
  },
  "version": 1
}

Rutas que puedes comprobar

Desplázate horizontalmente para ver todas las columnas.

Pointer (representado como cadena JSON) Valor
"" Documento completo
"/users/0/name" "Ana"
"/users/1/id" 2
"/a~1b~0c/" "value"

La última ruta incluye una clave con / y ~, seguida de una clave vacía. Escapa cada segmento sustituyendo primero ~ por ~0 y después / por ~1. Al decodificar, hazlo en orden inverso: ~1 y después ~0. Así ~01 representa la clave literal ~1.

"" y "/" son distintos: el segundo busca una propiedad de nombre vacío en la raíz. Los índices de array empiezan en cero y no admiten ceros iniciales: /users/01 no es válido para ese array. El token - no resuelve un elemento existente; JSON Patch lo utiliza para añadir al final.

Esto es la forma de cadena de RFC 6901. Un fragmento URI como #/users/0/name también requiere la codificación URI correspondiente; no añadas # a los campos path de JSON Patch. Si representas el Pointer dentro de JSON, también debes escapar las comillas y barras invertidas de la cadena JSON.

Un Patch completo: seis operaciones y resultado

Aplica este array al documento inicial de arriba, en orden:

[
  {
    "op": "test",
    "path": "/version",
    "value": 1
  },
  {
    "op": "replace",
    "path": "/users/0/name",
    "value": "Alicia"
  },
  {
    "op": "add",
    "path": "/users/-",
    "value": {
      "id": 3,
      "name": "Cyr"
    }
  },
  {
    "op": "copy",
    "from": "/a~1b~0c/",
    "path": "/snapshot"
  },
  {
    "op": "move",
    "from": "/users/1",
    "path": "/users/0"
  },
  {
    "op": "remove",
    "path": "/users/2"
  },
  {
    "op": "replace",
    "path": "/version",
    "value": 2
  }
]
  • test comprueba la versión antes de modificar.
  • replace cambia el nombre de Ana.
  • add añade a Cyr al final del array.
  • copy copia el valor de la clave vacía a snapshot.
  • move quita a Ben de su posición y lo inserta al principio.
  • remove elimina a Cyr, que sigue en el índice 2.
  • El último replace actualiza la versión.

Resultado esperado:

{
  "users": [
    {
      "id": 2,
      "name": "Ben"
    },
    {
      "id": 1,
      "name": "Alicia"
    }
  ],
  "a/b~c": {
    "": "value"
  },
  "version": 2,
  "snapshot": "value"
}

Cada operación ve el resultado de la anterior; los índices cambian al insertar o eliminar. add puede reemplazar una propiedad de objeto existente; en arrays inserta. El padre debe existir. replace y remove requieren un destino existente. copy y move requieren from; no se puede mover un nodo dentro de uno de sus descendientes. Estas reglas proceden de RFC 6902.

Errores y atomicidad

Si cambias el primer test a value: 99, falla antes de modificar este ejemplo. No confundas eso con una garantía de rollback de cualquier librería: al aplicar en memoria, una operación posterior puede fallar tras haber realizado otras. Trabaja sobre una copia y confirma el resultado solo cuando el conjunto termine correctamente.

HTTP PATCH exige aplicación atómica. En una API, usa Content-Type: application/json-patch+json si el servidor admite este formato. If-Match con el ETag recibido ayuda a evitar sobrescribir una versión distinta; el servidor debe comprobarlo. Un 412 indica que falló la precondición HTTP, no cualquier error de JSON Patch.

Cuándo usar Merge Patch

JSON Merge Patch, RFC 7396, usa application/merge-patch+json. Dentro de un objeto, null elimina una propiedad en lugar de asignarle null. Los arrays se reemplazan completos; no hay operaciones por índice. Un patch que no sea un objeto reemplaza el documento entero, incluso si es null.

Para cambios por campo suele ser más sencillo; usa JSON Patch cuando necesites asignar null a una propiedad o editar posiciones de arrays.

Continuar la comprobación

Compara el documento inicial y el resultado en JSON Diff. Para seleccionar varias coincidencias utiliza JSONPath. Ninguna de estas herramientas aplica el Patch de esta guía; comprueba el comportamiento y las opciones de mutación de la librería que utilices. No se garantiza que un generador produzca el patch más pequeño posible.

Herramientas relacionadas

Preguntas frecuentes

¿La raíz es /?

No. La raíz es la cadena vacía. / selecciona una propiedad cuyo nombre es vacío.

¿El visualizador aplica JSON Patch?

No. Permite explorar JSON y copiar rutas y valores. Esta guía muestra las operaciones y su resultado; JSON Diff compara documentos, no genera ni aplica un Patch.

¿Un fallo deshace los cambios de una librería?

No lo supongas. HTTP PATCH requiere aplicación atómica, pero una librería que modifica objetos en memoria puede dejar cambios parciales. Aplica sobre una copia y confirma solo si todo termina correctamente.

Por