Dev Tools

Guía de Sintaxis JSONPath: Expresiones, Filtros y Ejemplos Prácticos

Introducción: Por que JSONPath es importante en el desarrollo moderno

JSON se ha convertido en el formato dominante de intercambio de datos en APIs web, archivos de configuración, bases de datos y colas de mensajes. A medida que los documentos JSON crecen en complejidad — objetos profundamente anidados, arrays con cientos de elementos, estructuras de tipos mixtos — navegarlos manualmente se vuelve impractico. JSONPath proporciona un lenguaje de expresiones conciso y estandarizado para seleccionar y extraer valores específicos de documentos JSON, de manera similar a como XPath lo hace para XML.

Originalmente propuesto por Stefan Goessner en 2007, JSONPath ha sido formalizado como RFC 9535 (publicado en febrero de 2024), otorgando al lenguaje una especificacion oficial después de años de evolución informal impulsada por implementaciones. Ya sea que estes depurando respuestas de API, escribiendo pruebas automatizadas, transformando pipelines de datos o construyendo herramientas de gestion de configuración, comprender la sintaxis de JSONPath es una habilidad práctica que ahorra horas de inspeccion manual.

Esta guía cubre cada operador de JSONPath con ejemplos claros, compara JSONPath con XPath y jq, y demuestra patrones de extracción comunes contra respuestas de API realistas. Usa nuestra herramienta de consultas JSONPath para practicar estas expresiones de forma interactiva — todo el procesamiento ocurre localmente en tu navegador.

Sintaxis JSONPath: La referencia completa

Una expresión JSONPath es una cadena que describe una ruta a través de un documento JSON. Toda expresión comienza con $, que representa la raiz del documento. Desde ahí, se encadenan operadores para profundizar en objetos, iterar arrays y filtrar resultados. A continuacion se explica cada operador con ejemplos sobre un documento de muestra.

Considera este documento JSON de muestra utilizado en todos los ejemplos:

{
"tienda": {
"nombre": "TechBooks Online",
"libros": [
{ "titulo": "Design Patterns", "autor": "GoF", "precio": 49.99, "etiquetas": ["software", "oop"] },
{ "titulo": "Refactoring", "autor": "Fowler", "precio": 44.95, "etiquetas": ["software", "agile"] },
{ "titulo": "The Pragmatic Programmer", "autor": "Hunt", "precio": 39.99, "etiquetas": ["software", "carrera"] },
{ "titulo": "Clean Code", "autor": "Martin", "precio": 34.99, "etiquetas": ["software", "artesania"] },
{ "titulo": "Mythical Man-Month", "autor": "Brooks", "precio": 29.99, "etiquetas": ["gestion", "clásico"] }
],
"ubicación": { "ciudad": "Portland", "estado": "OR" }
}
}

Operador raiz: $

El signo de dolar $ siempre se refiere al elemento raiz del documento JSON. Toda expresión JSONPath debe comenzar con $. Por si solo, $ devuelve el documento completo. Es el ancla desde la cual comienzan todos los recorridos de ruta.

Expresión: $ — Devuelve el objeto JSON completo.

Operador hijo: Notacion de punto . y notacion de corchetes ['...']

El operador de punto . accede a una propiedad hija con nombre de un objeto. Es el operador más utilizado y refleja la sintaxis de acceso a propiedades de JavaScript. Para nombres de propiedades que contienen caracteres especiales, espacios o comienzan con un digito, utiliza la notacion de corchetes ['nombre-propiedad'] en su lugar.

  • $.tienda.nombre — Devuelve "TechBooks Online"
  • $.tienda.ubicación.ciudad — Devuelve "Portland"
  • $.tienda['nombre'] — Equivalente a $.tienda.nombre

La notacion de corchetes es necesaria cuando las claves contienen puntos, guiones o espacios (por ejemplo, $['content-type']). Ambas formas producen el mismo resultado para claves alfanumericas simples.

Descenso recursivo: ..

El operador de doble punto .. busca en todo el subarbol debajo del nodo actual. Es extremadamente útil cuando sabes que un nombre de propiedad existe en alguna parte profunda del documento pero no sabes (o no te importa) la ruta exacta.

  • $..autor — Devuelve todos los valores de autor a cualquier profundidad: ["GoF", "Fowler", "Hunt", "Martin", "Brooks"]
  • $..precio — Devuelve todos los valores de precio: [49.99, 44.95, 39.99, 34.99, 29.99]
  • $..etiquetas — Devuelve todos los arrays de etiquetas

El descenso recursivo es poderoso pero puede ser costoso en documentos muy grandes porque visita cada nodo en el subarbol. Usalo cuando la estructura sea impredecible o cuando necesites agregar valores dispersos en diferentes niveles de anidamiento.

Comodin: *

El comodin * coincide con todos los hijos del nodo actual, ya sean propiedades de objeto o elementos de array. Es útil para iterar todos los elementos en un nivel dado sin conocer sus nombres o indices.

  • $.tienda.libros[*].titulo — Devuelve todos los titulos de libros: ["Design Patterns", "Refactoring", "The Pragmatic Programmer", "Clean Code", "Mythical Man-Month"]
  • $.tienda.* — Devuelve los valores de todos los hijos directos de tienda: la cadena nombre, el array de libros y el objeto ubicación

Indice de array: [n]

Los corchetes con un indice entero basado en cero seleccionan un elemento específico de un array. Los indices negativos cuentan desde el final del array, siendo [-1] el último elemento.

  • $.tienda.libros[0] — Devuelve el primer objeto libro (Design Patterns)
  • $.tienda.libros[-1] — Devuelve el último objeto libro (Mythical Man-Month)
  • $.tienda.libros[0].titulo — Devuelve "Design Patterns"

Segmentacion de array: [inició:fin:paso]

El operador de segmentacion selecciona un rango de elementos de array, siguiendo la misma semantica que la notacion de segmentacion de Python. La sintaxis es [inició:fin:paso], donde inició es inclusivo, fin es exclusivo y paso controla el avance. Los tres componentes son opcionales.

  • $.tienda.libros[0:2] — Devuelve los primeros dos libros (indice 0 y 1)
  • $.tienda.libros[1:4] — Devuelve los libros en indice 1, 2 y 3
  • $.tienda.libros[-2:] — Devuelve los últimos dos libros
  • $.tienda.libros[::2] — Devuelve un libro de cada dos (indice 0, 2, 4)

La segmentacion es particularmente útil para operaciones tipo paginacion — extraer una ventana de resultados de un array grande sin necesidad de conocer el conteo total.

Unión: [n,m]

El operador de unión selecciona multiples indices específicos o nombres de propiedades en una sola expresión, devolviendo resultados de todas las ubicaciones especificadas.

  • $.tienda.libros[0,2,4] — Devuelve el primer, tercer y quinto libro
  • $.tienda.libros[0,2].titulo — Devuelve ["Design Patterns", "The Pragmatic Programmer"]

Expresiones de filtro: [?()]

Las expresiones de filtro son la caracteristica mas poderosa de JSONPath. Permiten seleccionar elementos que cumplan una condición booleana. El filtro se encierra en [?()], y @ se refiere al elemento actual que se esta evaluando.

  • $.tienda.libros[?(@.precio < 40)] — Devuelve libros con precio menor a 40
  • $.tienda.libros[?(@.autor == 'Fowler')] — Devuelve libros de Fowler
  • $.tienda.libros[?(@.precio >= 40 && @.precio <= 50)] — Devuelve libros con precio entre 40 y 50
  • $.tienda.libros[?(@.etiquetas[0] == 'software')] — Devuelve libros cuya primera etiqueta sea "software"

Los filtros soportan los operadores de comparación ==, !=, <, >, <=, >= y los operadores lógicos && (y), || (o). Algunas implementaciones también soportan funciones de coincidencia de cadenas y expresiones regulares dentro de los filtros.

JSONPath vs XPath: Mapeo de conceptos

JSONPath fue diseñado originalmente como un analogo JSON de XPath, el lenguaje de consultas para XML. Si ya conoces XPath, el siguiente mapeo te ayuda a traducir tu conocimiento existente:

  • / en XPath se convierte en . (punto) en JSONPath — ambos navegan a un elemento hijo
  • // en XPath se convierte en .. en JSONPath — descenso recursivo a través de todos los descendientes
  • * funciona de forma identica en ambos lenguajes — comodin que coincide con todos los hijos
  • [n] funciona de manera similar, pero los arrays en XPath son basados en 1 mientras que en JSONPath son basados en 0
  • Los predicados de XPath [condición] se mapean a los filtros de JSONPath [?(condición)]
  • XPath tiene ejes (parent, ancestor, following-sibling) que JSONPath no soporta — JSONPath solo recorre hacia abajo

La diferencia conceptual clave es que XPath opera sobre un arbol de nodos con atributos, contenido de texto y espacios de nombres, mientras que JSONPath opera sobre una estructura más simple de objetos, arrays y valores primitivos. Las expresiones JSONPath son típicamente más cortas y mas intuitivas para datos JSON porque la estructura de JSON es inherentemente más simple que la de XML.

Otra distincion importante: XPath puede navegar hacia arriba a nodos padre y ancestro, mientras que el JSONPath estandar solo puede recorrer hacia abajo desde la raiz. Esto significa que en JSONPath no puedes seleccionar un objeto padre basandote en el valor de un hijo — solo puedes filtrar arrays de objetos basandote en sus propias propiedades.

JSONPath vs jq: Herramientas diferentes para contextos diferentes

Mientras que JSONPath es un lenguaje de consultas integrado en aplicaciones y APIs, jq es una herramienta y lenguaje independiente de linea de comandos para transformar JSON. Sirven propositos superpuestos pero distintos:

  • Consulta (selección): Tanto JSONPath como jq pueden extraer valores de JSON. JSONPath usa $.store.books[0].title, mientras que jq usa .store.books[0].title — la sintaxis es casi identica para rutas simples.
  • Transformacion: jq puede crear nuevas estructuras JSON, realizar aritmetica, concatenar cadenas, agrupar y ordenar datos, y canalizar resultados a través de multiples etapas. JSONPath es puramente un lenguaje de selección — extrae valores existentes pero no los transforma.
  • Filtrado: El [?(@.price < 40)] de JSONPath se mapea al select(.price < 40) de jq. Ambos son expresivos para condiciones básicas. jq es mas poderoso para lógica compleja de multiples condiciones con variables y funciones.
  • Entorno: JSONPath esta disponible como biblioteca en prácticamente todos los lenguajes de programacion (JavaScript, Python, Java, Go, PHP, C#) y puede integrarse en APIs, bases de datos (PostgreSQL, MySQL) y archivos de configuración. jq es principalmente una herramienta de linea de comandos, aunque existen bibliotecas para uso programatico.
  • Curva de aprendizaje: La sintaxis de JSONPath es más simple y se puede aprender en minutos. jq es un lenguaje de programacion funcional completo con pipes, variables, condicionales y funciones definidas por el usuario — mas poderoso pero con una curva de aprendizaje mas pronunciada.

En la práctica, usa JSONPath cuando necesites integrar consultas dentro del codigo de aplicación, parametros de API o archivos de configuración (por ejemplo, plantillas JSONPath de Kubernetes, AWS Step Functions). Usa jq cuando proceses JSON en la linea de comandos o en scripts de shell donde sus capacidades de transformacion brillan.

Ejemplos prácticos: Consultando respuestas reales de API

El verdadero valor de JSONPath se hace evidente al trabajar con respuestas de API del mundo real. Aquí hay patrones comunes que encontraras regularmente.

Respuesta paginada de API REST

Una respuesta típica de API paginada envuelve los datos en un sobre de metadatos:

{
"data": [
{ "id": 1, "nombre": "Alice", "rol": "admin", "activo": true },
{ "id": 2, "nombre": "Bob", "rol": "editor", "activo": true },
{ "id": 3, "nombre": "Charlie", "rol": "viewer", "activo": false }
],
"meta": { "total": 150, "pagina": 1, "porPagina": 3 }
}

  • $.data[*].nombre — Extraer todos los nombres de usuario: ["Alice", "Bob", "Charlie"]
  • $.data[?(@.activo == true)].nombre — Solo usuarios activos: ["Alice", "Bob"]
  • $.data[?(@.rol == 'admin')] — Encontrar usuarios administradores
  • $.meta.total — Obtener el conteo total de registros: 150

Objeto de configuración anidado

Las configuraciones de aplicaciones frecuentemente anidan ajustes varios niveles de profundidad:

{
"app": {
"baseDatos": {
"primaria": { "host": "db1.example.com", "puerto": 5432 },
"replica": { "host": "db2.example.com", "puerto": 5432 }
},
"cache": { "host": "redis.example.com", "puerto": 6379 }
}
}

  • $..host — Encontrar todos los valores de host a cualquier profundidad: ["db1.example.com", "db2.example.com", "redis.example.com"]
  • $..puerto — Encontrar todos los valores de puerto: [5432, 5432, 6379]
  • $.app.baseDatos.primaria.host — Obtener el host específico de la base de datos primaria

Respuesta anidada estilo GraphQL

Las respuestas de GraphQL a menudo incluyen relaciones profundamente anidadas:

{
"data": {
"repositorio": {
"issues": {
"nodos": [
{ "titulo": "Bug en login", "estado": "ABIERTO", "etiquetas": { "nodos": [{ "nombre": "bug" }, { "nombre": "urgente" }] } },
{ "titulo": "Agregar modo oscuro", "estado": "ABIERTO", "etiquetas": { "nodos": [{ "nombre": "feature" }] } },
{ "titulo": "Corregir typo", "estado": "CERRADO", "etiquetas": { "nodos": [{ "nombre": "docs" }] } }
]
}
}
}
}

  • $.data.repositorio.issues.nodos[*].titulo — Todos los titulos de issues
  • $.data.repositorio.issues.nodos[?(@.estado == 'ABIERTO')].titulo — Solo issues abiertos
  • $..etiquetas.nodos[*].nombre — Todos los nombres de etiquetas en todos los issues

Patrones y recetas comunes de JSONPath

Ciertos patrones de extracción aparecen repetidamente en diferentes casos de uso. Aquí hay una referencia rápida de recetas que puedes adaptar a tus estructuras de datos específicas.

Extraer una lista plana de arrays anidados

Cuando los datos estan anidados dentro de arrays de arrays, los operadores de descenso recursivo y comodin se combinan para aplanar los resultados. Por ejemplo, $..items[*].name extrae todos los valores de name de cualquier array items a cualquier nivel de anidamiento, sin importar cuántas capas de profundidad tenga el array.

Verificar la existencia de una propiedad

Algunas implementaciones de JSONPath soportan una verificación de existencia dentro de los filtros. La expresión $.data[?(@.email)] selecciona solo objetos que tienen una propiedad email definida (no nula, no ausente). Esto es útil al tratar con respuestas de API inconsistentes donde campos opcionales pueden o no estar presentes.

Combinar multiples condiciones

Los filtros complejos usan operadores lógicos para combinar condiciones: $.productos[?(@.precio > 10 && @.precio < 100 && @.enStock == true)] selecciona productos dentro de un rango de precio que también estan en stock. Usa parentesis para agrupar condiciones al mezclar && y || para asegurar el orden correcto de evaluación.

Seleccionar los últimos N elementos

La segmentacion negativa facilita tomar el final de un array. $.logs[-5:] devuelve las últimas cinco entradas de log de un array, lo cual es un patron comun al mostrar actividad reciente o los últimos mensajes de error de un flujo de logs.

JSONPath en el ecosistema: Donde se utiliza

JSONPath no es solo un lenguaje de consultas teorico — esta integrado en muchas herramientas y plataformas de producción:

  • Kubernetes: El comando kubectl get soporta el formato de salida -o jsonpath='{...}', permitiendote extraer campos específicos de descripciones de recursos directamente en tu terminal.
  • PostgreSQL: La función jsonb_path_query soporta SQL/JSON Path, que esta basado en los mismos conceptos que JSONPath y usa sintaxis similar para consultar columnas JSONB.
  • AWS Step Functions: El procesamiento de entrada y salida en definiciones de maquinas de estado usa expresiones JSONPath (con prefijo $.) para enrutar datos entre pasos.
  • Jayway JsonPath (Java): La implementación Java más utilizada, comunmente usada en aplicaciones Spring Boot y pruebas de API con REST Assured.
  • Herramientas de pruebas de API: Postman, REST Assured, Karate y herramientas similares usan JSONPath para escribir aserciones contra cuerpos de respuesta de API.
  • Azure Logic Apps y Power Automate: Las expresiones JSONPath se usan en evaluaciones de condiciones y mapeo de datos dentro de la automatización de flujos de trabajo.

Mejores prácticas para escribir expresiones JSONPath

Seguir estas directrices hará que tus expresiones JSONPath sean mas robustas, mantenibles y portables entre implementaciones:

  • Se lo más específico posible. Prefiere $.store.books[*].title sobre $..title cuando conoces la ruta exacta. Las rutas específicas son mas rápidas y menos propensas a devolver resultados inesperados de partes no relacionadas del documento.
  • Usa el descenso recursivo con moderacion. El operador .. busca en cada nodo del subarbol. En documentos grandes (megabytes de JSON), esto puede ser lento. Usalo cuando la estructura sea genuinamente impredecible.
  • Prueba con casos extremos. Un array vacio, una propiedad ausente, un valor nulo y un documento con un solo elemento ejercitan diferentes rutas de codigo. Verifica que tu expresión maneje cada caso correctamente.
  • Documenta tus expresiones. Las expresiones JSONPath integradas en archivos de configuración o aserciones de prueba deben tener un comentario explicando que extraen y por que, especialmente para expresiones de filtro complejas.
  • Ten en cuenta las diferencias entre implementaciones. A pesar del RFC 9535, no todas las bibliotecas implementan cada caracteristica de manera identica. Prueba tus expresiones en la biblioteca específica que estes usando. Nuestra herramienta de consultas JSONPath usa una implementación compatible con estandares que puedes usar como linea base de referencia.
  • Prefiere la notacion de corchetes para caracteres especiales. Si una clave contiene puntos, espacios o guiones, siempre usa $['mi-clave'] en lugar de intentar la notacion de punto, que fallara o producira resultados inesperados.

Conclusión: JSONPath como habilidad esencial del desarrollador

JSONPath cierra la brecha entre los datos JSON crudos y los valores específicos que tu aplicación necesita. Su sintaxis concisa — raiz $, hijo ., recursivo .., comodin *, indice [n], segmentacion [inició:fin] y filtro [?()] — cubre la gran mayoría de escenarios de extracción de datos que encontraras en la práctica. Con el RFC 9535 proporcionando una especificacion formal, JSONPath ya no es una coleccion suelta de implementaciones compatibles pero diferentes; es una herramienta estandarizada en la que puedes confiar a través de lenguajes y plataformas.

Para experimentacion rápida y validación de tus expresiones JSONPath, usa nuestra herramienta de consultas JSONPath. Pega tu JSON, escribe tu expresión y ve los resultados al instante — con todo el procesamiento ocurriendo completamente en tu navegador para total privacidad.

← Volver al Blog