JSON JMESPath Extractor
Table of Contents
Intermedio - This article is part of a series.
¿ Qué es JMESPath ? #
JMESPath fue desarrollado en 2012 por James Saryerwinnie, un ingeniero de software de Mozilla Corporation, como una alternativa a JSONPath para acceder y manipular datos en documentos JSON. La motivación principal detrás de la creación de JMESPath fue el de una herramienta más eficiente y flexible para acceder a los datos en los documentos JSON que se utilizan ampliamente en aplicaciones web y móviles.
En los años siguientes, JMESPath se hizo cada vez más popular entre los desarrolladores que trabajan con aplicaciones web y móviles que utilizan JSON como formato de intercambio de datos. JMESPath se integró con varias bibliotecas y herramientas populares de Python y se convirtió en una herramienta clave para la gestión de infraestructura en la nube. En 2017, JMESPath se convirtió en un proyecto independiente de código abierto bajo la organización de proyectos de Python. Desde entonces, ha sido adoptado por varias bibliotecas y herramientas populares de Python, como AWS CLI y Terraform, y se ha utilizado en una variedad de contextos, desde el análisis de datos hasta la integración de sistemas y la automatización de procesos.
Hoy en día, JMESPath sigue siendo una herramienta popular para acceder y manipular datos en documentos JSON en aplicaciones web y móviles. Es compatible con una amplia variedad de lenguajes de programación y marcos, y se utiliza en una variedad de contextos, como la gestión de infraestructura en la nube, el análisis de datos y la automatización de procesos.
¿ Qué es JSON ? #
JSON (JavaScript Object Notation) es un formato de texto ligero y fácil de leer para el intercambio de datos. Se utiliza comúnmente para transmitir información entre una aplicación cliente y un servidor o para transmitir datos entre aplicaciones. JSON representa datos en forma de objetos anidados y listas de objetos, y utiliza una sintaxis clara y fácil de leer basada en llaves { } para definir objetos y corchetes [ ] para definir listas.
Las propiedades de un objeto JSON se representan como pares clave y valor { "nombre" : "Ana" } separados por dos puntos : como se puede ver en el siguiente jemplo:
{
"nombre": "Ana",
"edad": 28,
"direccion": {
"calle": "Calle Principal",
"ciudad": "Ciudad de México",
"estado": "Ciudad de México",
"codigo_postal": "12345"
},
"intereses": ["leer","viajar","cocinar"]
}
¿ Cómo funciona JMESPath en JMeter ? #
En JMeter, JMESPath es un Post-procesador que permite extraer valores específicos de una respuesta JSON. Para ello debemos seguir los siguientes pasos:
- Agregue un elemento HTTP Request o Dummy Sampler a su plan de prueba de JMeter para realizar una solicitud HTTP y recibir una respuesta JSON.
- Agregue un extractor JMESPath Extractor al elemento antes mencionado, este extractor se encargará de extraer los valores específicos que se necesitan de la respuesta JSON.
- Configure los campos requeridos en el post-procesador JMESPath Extractor como se muestra en la siguiente tabla:
Atributo | Descripción | Requerido |
---|---|---|
Nombre | Nombre descriptivo para este elemento que se muestra en el árbol. | No |
Aplicar a | Útil para su uso con muestreadores que pueden generar sub-muestras, como el muestreador HTTP con recursos incrustados, Mail Reader o las muestras generadas por el controlador de transacciones. Muestra principal solamente: solo se aplica a la muestra principal Solo sub-muestras: solo se aplica a las sub-muestras Muestra principal y sub-muestras: se aplica a ambas Nombre de la variable JMeter a utilizar: la extracción se aplicará al contenido de la variable nombrada | Sí |
Nombre de la variable creada | El nombre de la variable JMeter en la que se almacenará el resultado. | Sí |
Expresiones JMESPath | Consulta de elemento en el lenguaje de consulta JMESPath. Puede devolver el resultado coincidente. | Sí |
Número de coincidencias (0 para aleatorio) | Si la consulta JMESPath tiene muchos resultados, puedes elegir cuál(es) extraer como variables: 0: significa aleatorio -1: significa extraer todos los resultados (valor predeterminado), se llamarán como <nombre de la variable>_N (donde N va de 1 al número de resultados) X: significa extraer el resultado X (enésimo). Si este X (enésimo) es mayor que el número de coincidencias, no se devuelve nada. Se utilizará el valor predeterminado | No |
Valor predeterminado | Valor predeterminado devuelto cuando no se encuentra ninguna coincidencia. También se devuelve si el nodo no tiene valor y no se selecciona la opción de fragmento. | No |
Ejemplo:
{
"nombre": "Ana",
"edad": 28,
"direccion": {
"calle": "Calle Principal",
"ciudad": "Ciudad de México",
"estado": "Ciudad de México",
"codigo_postal": "12345"
},
"intereses": ["leer","viajar","cocinar"]
}
Podemos utilizar la siguiente expresión JMESPath para extraer estos valores:
nombre //Ana
edad //28
direccion.calle //Calle Principal
direccion.codigo_postal //12345
direccion.ciudad //Ciudad de México
hobbies //["leer","viajar","cocinar"]
¿ Qué otros ejemplos de uso pudiera tener JMESPath ? #
Supongamos un ejemplo más complejo, como el siguiente:
[{
"name": "John Doe",
"age": 35,
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "WA"
},
"phoneNumbers": [
{
"type": "mobile",
"number": "555-551-1234"
},
{
"type": "home",
"number": "555-552-5678"
}
],
"email": "john.doe@example.com"
},{
"name": "Peter Doe",
"age": 34,
"address": {
"street": "123 Second St",
"city": "RacconCity",
"state": "TX"
},
"phoneNumbers": [
{
"type": "mobile",
"number": "555-553-1234"
},
{
"type": "home",
"number": "555-554-5678"
}
],
"email": "peter.doe@example.com"
},{
"name": "Rick Doe",
"age": 36,
"address": {
"street": "123 Third St",
"city": "Springfield",
"state": "NJ"
},
"phoneNumbers": [
{
"type": "mobile",
"number": "555-555-1234"
},
{
"type": "home",
"number": "555-556-5678"
}
],
"email": "rick.doe@example.com"
}]
Para este ejemplo, supogamos que deseamos evaluar y extraer los siguiente datos:
Expresión | Resultado |
---|---|
[*].name | devuelve todos los nombres de las personas. |
[0].phoneNumbers[0].number | devuelve el número de teléfono móvil del primer objeto phoneNumbers. |
[?address.state=='WA'].name | devuelve los nombres de personas cuyo estado es WA. |
[*].phoneNumbers[?type=='mobile'].number | devuelve los números de teléfono móvil de los objetos phoneNumbers. |
length([*].phoneNumbers[?type=='home']) | devuelve el número de objetos phoneNumbers de tipo home. |
sort_by(@, &age)[0].name | devuelve el nombre de la persona más joven. |
sort_by(@, &age)[-1].name | devuelve el nombre de la persona más vieja. |
max_by(@, &age).name | devuelve el nombre de la persona más vieja. |
min_by(@, &age).name | devuelve el nombre de la persona más joven. |
[*].name | sort(@) | devuelve una lista de los nombres de las personas en orden alfabético. |
sum([*].age) | devuelve la suma de todas las edades. |
length([*].phoneNumbers) | devuelve la cantidad de números de teléfono. |
join(', ', [*].phoneNumbers[].number) | devuelve una cadena que contiene una lista de todos los números de teléfono. |
[?age >= `35` ] | devuelve los nombres de personas cuya edad es mayor que 35. |
[?age >= `35`] | [?address.state == ‘WA’].name | devuelve los nombres de personas cuya edad es mayor de 35 y que viven en WA. |
[?contains(email,'john')].email | [0] | devuelve la dirección de correo electrónico de la persona cuyo nombre contiene john. |
[?contains(name, 'Doe')].phoneNumbers[].number | [1] | devuelve el segundo número de teléfono de las personas cuyo nombre contiene Doe. |
[?address.state=='TX'].address.city | sort(@) | [0] | devuelve el nombre de la ciudad más pequeña en Texas. |
[*].name | reverse(@) | devuelve los nombres de las personas de mayor a menor. |
[*].age | sum(@) | devuelve la suma de todas las edades. |
Para evaluar estas sentencias, te recomiendo utilizar un receptor View results tree y utilizar la vista en JSON JMESPath Tester e introducir la sentencia en el campo JMESPath Expression y dar click en el boton Test
Conclusión #
JMESPath es una herramienta muy poderosas para extraer un valor, multiples valores, evaluación o ejecución de funciones de los valores para satisfacer uno o varios criterios, recuerda siempre practicar antes de desarrollar tu sentencia o expression. Siempre es bueno verificar los criterios ante varios tipos de respuestas diferentes para obtener resultados contundentes. Hay que practicar, hasta la próxima!