20 September 2019

Pruebas de carga a un servicio GraphQL con k6

Pepe Cano

La popularidad y adopción de GraphQL ha sido impresionante en los últimos años, y a medida que más usuarios empiezan a descubrir K6, hemos estado recibiendo una gran cantidad de preguntas sobre GraphQL. Con el siguiente post queremos proporcionar información útil para aquellos que empiezan a usar K6 a la hora de hacer pruebas a un servicio GraphQL.

¿Admite k6 las pruebas a un servicio GraphQL?

La respuesta es SÍ. K6 soporta las pruebas de servicios GraphQL que se ejecutan sobre HTTP o WebSocket.

Pero me gustaría profundizar un poco más en esta respuesta porque nos hemos dado cuenta de que algunos usuarios están ligeramente confundidos sobre cómo funciona GraphQL o K6.

GraphQL es un "lenguaje" de transporte independiente

GraphQL es un lenguaje para consultar y manipular las APIs; la especificación define la sintaxis para comunicarse con una API GraphQL.

Por ejemplo, dado un esquema de un API:

type Query {
me: User
}
type User {
id: ID
name: String
}

La consulta sería:

{
me {
name
}
}

GraphQL es agnóstico en cuanto a la capa de transporte; no restringe un servidor GraphQL a ejecutarse sobre un protocolo de transporte en particular. HTTP es la opción común debido a su ubicuidad, pero un servidor GraphQL podría ejecutarse sobre diferentes protocolos como:

  • HTTP, AMQP, Websockets, entre otros.
  • Protocolos de bajo nivel: TCP, UDP, gRPC, entre otros.

Por otro lado, K6, toma el papel de cliente de GraphQL, se pueden generar peticiones sobre HTTP o Websocket en el momento de escribir este post. Esto significa que K6 puede probar cualquier servidor GraphQL que se ejecute sobre uno de los protocolos de K6 soportados.

Ejemplo de una prueba de la API GraphQL de GitHub

Vamos a intentar mostrar rápidamente un ejemplo usando K6 para probar un servicio GraphQL. Para evitar la configuración y ejecución de nuestro propio servidor GraphQL, cargaremos la prueba de la API GraphQL de GitHub. Estamos eligiendo la API de GitHub porque es familiar para muchos desarrolladores, está bien documentada y tiene múltiples tipos de esquemas, consultas y mutaciones con las que podemos jugar.

Para empezar, necesitamos un Token Personal de GitHub para autenticarnos con la API de GitHub. Consulte la siguiente guía para crear un Token Personal para ejecutar esta prueba. Dependiendo de las peticiones de nuestra prueba, tu token necesitará diferentes permisos o alcances. Para el siguiente ejemplo, tu token necesita los siguientes permisos:

  • Acceder a los repositorios públicos: repo:public_repo
  • Leer y escribir discusiones de equipo: write:discussion
¿Cómo puedo crear mi primera solicitud usando GraphQL?

Debido a que la API GraphQL de GitHub se ejecuta a través de HTTP, y las consultas o mutaciones GraphQL requieren un cuerpo codificado en JSON, utilizarás la función http.post para generar peticiones que lleguen a la API.

Podríamos empezar nuestra prueba obteniendo algunos datos de la API de GitHub:

¿Cuál fue el primer issue de GitHub del proyecto K6?

El código es bastante sencillo; sólo tienes que poner tu Token en la cabecera de la Autorización, escribir la consulta GraphQL (Objeto/Repositorio/Issues) y enviarla en la petición POST.

const accessToken = 'TOKEN_DE_GITHUB';
const query = `
query FindFirstIssue {
repository(owner:"grafana", name:"k6") {
issues(first:1) {
edges {
node {
id
number
title
}
}
}
}
}`;
const headers = {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
};
const res = http.post('https://api.github.com/graphql', JSON.stringify({ query: query }), {
headers: headers,
});

Ahora mismo, nuestro script de K6 se limita a llamar el endpoint para solicitar siempre los mismos datos, pero en realidad lo que queríamos era crear una prueba para replicar una interacción concreta del usuario.

Depuración de datos en la respuesta

Mientras desarrollas tu script, puede que quieras ver el contenido de la respuesta para validar los datos o utilizarlo en tu test de carga.

if (res.status === 200) {
console.log(JSON.stringify(res.body));
const body = JSON.parse(res.body);
const issue = body.data.repository.issues.edges[0].node;
console.log(issue.id, issue.number, issue.title);
}

La respuesta será algo como lo siguiente:

INFO[0001] "{"data":{"repository":{"issues":{"edges":[{"node":{"id":"MDU6SXNzdWUxNzA0MzczOTY=","number":4,"title":"Deduplicate HTTP client code"}}]}}}}"
INFO[0001] MDU6SXNzdWUxNzA0MzczOTY= 0=4 1="Deduplicate HTTP client code"
Ejecutando una mutación para añadir una reacción 🎉 al primer issue de K6.

Este sencillo ejemplo pretende mostrar cómo actualizar los datos del servidor en base a los datos obtenidos de otra petición. En GraphQL, utilizarás mutaciones para modificar los datos.

Puedes leer los documentos para añadir una reacción o encontrar ejemplos para aprender la sintaxis de esta mutación. En este caso, la mutación añadir una reacción necesita el issue.id para añadir la reacción 🎉 al issue. A continuación se muestra un ejemplo:

const mutation = `
mutation AddReactionToIssue {
addReaction(input:{subjectId:"${issue.id}",content:HOORAY}) {
reaction {
content
}
subject {
id
}
}
}`;
res = http.post('https://api.github.com/graphql', JSON.stringify({ query: mutation }), {
headers: headers,
});

Ahora, puedes ejecutar la prueba y comprobar la reacción a la emisión de K6 pasando el mouse por encima del siguiente ícono 🎉 . Aqui puedes consultar el ejemplo completo.

Conclusión

Cada vez recibimos más preguntas sobre GraphQL:

Probar GraphQL con k6 es tan sencillo como generar una petición con datos. El post también incluye un ejemplo básico para dar un punto de partida para probar un servicio GraphQL con K6. Hemos querido ser breves, pero las posibilidades son infinitas, el script de K6 y las opciones de K6 permiten ejecutar un amplio abanico de pruebas de rendimiento de distintos tipos.

Ver también

< Back to all posts