Mutaciones en GraphQL: sintaxis, variables y tipos input | We.Inc
Escribe mutaciones GraphQL que crean, actualizan y borran datos: sintaxis de la operación, $variables, tipos de objeto input, qué devolver y cómo se ven los errores y el éxito parcial.
Una mutación de GraphQL es la operación que envías para cambiar datos. Empieza con la palabra clave mutation, invoca un campo del tipo Mutation del esquema, pasa argumentos, normalmente un objeto input guardado en una $variable, y selecciona qué campos del resultado devolver. Los campos de mutación de nivel superior se ejecutan uno tras otro, nunca en paralelo.
La sintaxis de una mutación por partes
Parte
Ejemplo
Qué hace
Palabra clave y nombre
mutation AddTask
Marca la operación como escritura y le da nombre para los logs
Definición de variables
($input: TaskInput!)
Declara valores tipados que se envían aparte como JSON
Campo raíz
addTask(input: $input)
Un campo definido en el tipo Mutation
Conjunto de selección
{ id title done }
Campos del resultado que se devuelven
JSON de variables
{"input": {...}}
Los valores reales, fuera del texto de la consulta
Usa el generador de abajo para ver una mutación completa para una pequeña lista de tareas: la operación, el JSON de variables que tu código enviaría con ella y una respuesta típica. Escribe el título de una tarea y mira cómo se actualizan las variables, así puedes copiar una petición lista para ejecutar contra un esquema equivalente.
Elige crear, actualizar o borrar.
Escribe un título para la tarea; el JSON de variables se actualiza mientras escribes.
Copia la mutación y las variables, y envíalas como las claves query y variables de un único POST.
Compara la respuesta de tu servidor con la respuesta de ejemplo que aparece debajo.
Envía los valores mediante variables en lugar de pegarlos en el texto de la consulta. Evita errores de escape y permite que los servidores guarden en caché el documento analizado.
Devuelve el objeto modificado, incluido su id, para que las cachés del cliente actualicen la pantalla sin una segunda petición.
Ponle nombre a cada operación. Las mutaciones con nombre son mucho más fáciles de encontrar en los logs del servidor y en los informes de errores.
Trata varios campos raíz en una misma mutación como pasos separados, no como una transacción: un campo anterior queda hecho aunque falle uno posterior.
Preguntas frecuentes
¿Qué diferencia hay entre una query y una mutation?
Ambas usan la misma sintaxis y ambas pueden devolver datos. Por convención, las queries solo leen y las mutations escriben. La regla de ejecución también cambia: los campos de una query pueden resolverse en paralelo, mientras que los campos de mutación de nivel superior se ejecutan en serie.
¿Por qué usar un tipo input en lugar de argumentos sueltos?
Un objeto input agrupa valores relacionados en un único argumento tipado, así la firma de la mutación se mantiene corta y puedes añadir campos opcionales más adelante sin cambiar cada llamada.
¿Puedo enviar una mutación con una petición GET?
No. Las pautas de GraphQL over HTTP permiten a los servidores aceptar GET solo para operaciones query. Las mutaciones van por POST, lo que además mantiene las escrituras fuera de las cachés del navegador y de la CDN.
¿Es atómica una mutación con varios campos?
No. graphql.org señala que la ejecución en serie no es una transacción de base de datos. Si el segundo campo falla, el cambio del primero se mantiene, y la respuesta contiene datos para uno y un error para el otro.
¿Qué debería devolver una mutación de borrado?
La especificación lo deja en tus manos, pero el campo sigue necesitando un tipo de salida. Las opciones habituales son el id del objeto borrado, el propio objeto eliminado o un tipo payload con el id y un indicador de éxito.
Anatomía de una mutación
En el servidor, el esquema declara un tipo Mutation cuyos campos son las escrituras que pueden invocar los clientes, cada una con argumentos y un tipo de retorno. En el cliente, la operación nombra uno o varios de esos campos, pasa argumentos y elige los campos del resultado que quiere recibir.
Si el campo devuelve un tipo de objeto, hace falta un conjunto de selección, igual que en una query. Pedir el id nuevo y los campos que muestra la pantalla permite al cliente actualizar su vista directamente desde la respuesta.
Variables y objetos input
Las variables se declaran después del nombre de la operación con un signo de dólar y un tipo, como $input: TaskInput!. El signo de exclamación hace que la variable sea obligatoria. Los valores viajan en un objeto variables aparte dentro del cuerpo de la petición.
Un tipo de objeto input se declara con la palabra clave input en lugar de type. Sus campos solo pueden ser escalares, enums, listas u otros tipos input, lo que hace que la forma de lo que envían los clientes sea fácil de validar.
Errores en una escritura
Si el documento no es válido, por ejemplo por un campo mal escrito o una variable obligatoria que falta, el servidor responde con errores y sin datos, y no se escribe nada.
Si la propia escritura falla durante la ejecución, el campo vuelve como null y una entrada de errors lleva un mensaje y una ruta. Muchos esquemas devuelven además los problemas previstos, como un título demasiado largo, como campos de un tipo payload para que el cliente pueda mostrarlos junto al formulario.
El esquema detrás de los ejemplos
Tipo Mutation y tipos input
Los tipos input usan la palabra clave input. TaskPatch no tiene campos obligatorios, así que una actualización puede enviar solo lo que cambia.
Enviarla desde JavaScript
Envía la mutación por POST con fetch
El documento y las variables viajan como dos claves de un único cuerpo JSON. Revisa errors incluso cuando el estado es 200.
Dos escrituras en una operación
Los alias permiten ejecutar el mismo campo dos veces. El segundo solo se ejecuta cuando termina el primero, pero si falla no deshace el primero.
Crear
El tipo input agrupa los campos de la nueva tarea. El conjunto de selección pide el id que asignó el servidor.
Actualizar
El id indica qué tarea cambiar y el input lleva solo los campos que cambian.
Borrar
En una tarea eliminada no queda nada que seleccionar, así que este esquema devuelve el id borrado como un escalar ID simple.
Generador de mutaciones
Elige una mutación
Título de la tarea
Mutación
Variables (JSON)
Respuesta de ejemplo
Copiar mutación
Copiar variables
Borrar solo necesita el id, así que el título no se envía.