FlowingDev

GraphQL, con estilo: el lenguaje secreto de los queries y esquemas ordenados

Aprende por qué el código GraphQL con formato consistente —desde queries hasta esquemas— es crucial para la legibilidad, la depuración y la colaboración en equipo.

Probar la herramienta: Formateador GraphQL

En una frase

El formateo de GraphQL es el arte de aplicar reglas de estilo consistentes a queries, mutaciones y esquemas, convirtiendo un revoltijo de llaves y campos en una obra maestra legible y mantenible.

El problema que resuelve

En los viejos tiempos, si querías obtener datos de un servidor para tu nueva y genial aplicación web, probablemente usarías una API REST. Pedirías datos de usuario a un endpoint como /users/123 y sus posts a /users/123/posts. ¿El problema? Podrías recibir muchos más datos de usuario de los que necesitabas (over-fetching), o tendrías que hacer múltiples viajes de ida y vuelta para obtener todos los datos que sí necesitabas (under-fetching).

Entra en escena GraphQL, un lenguaje de consulta para APIs desarrollado por Facebook. Cambió las reglas del juego. En lugar de que el servidor decida qué datos enviar, el cliente pide exactamente lo que necesita, todo en una sola petición. Es como pedir a la carta en lugar de recibir un menú fijo.

# Dame solo el nombre del usuario 42 y los títulos de sus primeros 3 posts
query GetUserNameAndPosts {
  user(id: "42") {
    name
    posts(first: 3) {
      title
    }
  }
}

Esto fue una revolución. Pero introdujo un problema nuevo, a menor escala. Los queries de GraphQL, con sus llaves anidadas, pueden volverse complejos. Realmente complejos. Sin reglas, un query escrito por un desarrollador podría parecer una sola línea de texto ilegible. Otro desarrollador podría escribir el mismo query con un estilo de indentación completamente diferente.

Cuando estás intentando depurar un problema a las 2 de la mañana o un nuevo miembro del equipo está tratando de entender la estructura de tu API, esta falta de consistencia es una pesadilla. El código es comunicación, y un GraphQL sin formato es como intentar leer un libro sin párrafos, puntuación o una tipografía consistente. El formateo impone una gramática compartida, haciendo la intención del código instantáneamente más clara para cada humano que lo lea.

Cómo funciona por dentro

Un formateador de GraphQL no está haciendo simplemente un elegante "buscar y reemplazar". Es un proceso sofisticado que implica entender la estructura del código, aplicar un conjunto de reglas y luego reconstruir el código desde cero de una manera hermosa y predecible.

Parseo: De texto a árbol

Primero, el formateador tiene que leer la cadena de texto cruda del código GraphQL y entender qué es. No puede simplemente buscar un { y añadir una nueva línea. Necesita saber si esa llave está abriendo un query, la definición de un tipo o un objeto de entrada.

Este proceso se llama parseo. El formateador tokeniza la entrada (la divide en trozos significativos como query, user, (, id, :, "42", )) y luego construye un Árbol de Sintaxis Abstracta (AST). El AST es una estructura de datos tipo árbol que representa la estructura gramatical del código.

Para un query simple:

query { user { name } }

El AST podría verse algo así (de una manera conceptual y simplificada):

- Document
  - Definition (OperationDefinition, type: query)
    - SelectionSet
      - Selection (Field)
        - name: "user"
        - SelectionSet
          - Selection (Field)
            - name: "name"

El texto ya no es solo texto; es un objeto estructurado que el programa puede manipular de forma inteligente.

Las reglas de estilo

Una vez que el formateador tiene el AST, puede recorrer el árbol y aplicar sus reglas de estilo. Estas reglas son el corazón del formateo y a menudo son objeto de debates de desarrolladores (casi siempre inútiles). Las reglas comunes incluyen:

  • Indentación: Cuántos espacios (o tabuladores, si eres un monstruo) usar para cada nivel de anidación. El estándar casi universal es de 2 espacios.
  • Saltos de línea: Cuándo poner las cosas en una nueva línea. ¿Debería una llave de apertura { estar en la misma línea que el nombre del campo o en una nueva línea? (La mayoría de los formateadores la ponen en la misma línea).
  • Espaciado: Asegurar un espacio consistente alrededor de operadores como los dos puntos y dentro de los paréntesis.
  • Ordenamiento de campos: Para esquemas grandes, algunos formateadores pueden incluso ordenar los campos alfabéticamente para que sean más fáciles de encontrar.

Herramientas como Prettier se han hecho famosas por ser "dogmáticas" (opinionated) —toman estas decisiones por ti, para que no tengas que discutirlas. El objetivo no es encontrar el único estilo "perfecto", sino elegir un estilo y aplicarlo implacablemente.

Pretty-Printing: del árbol de vuelta a texto

Después de aplicar las reglas, el trabajo final del formateador es tomar el AST modificado y convertirlo de nuevo en una cadena de texto. Este proceso se llama pretty-printing. El formateador recorre el árbol y, en cada nodo (como Field o SelectionSet), imprime el texto correspondiente, añadiendo la indentación y los saltos de línea correctos según las reglas.

El resultado es una cadena de GraphQL hermosamente formateada.

Un concepto relacionado es la minificación o compactación. Esto es lo contrario del pretty-printing. También parsea el código a un AST, pero luego lo imprime de nuevo eliminando todo el espacio en blanco opcional. Esto crea una cadena compacta de una sola línea, ilegible para los humanos pero perfecta para enviar por la red, ya que ahorra unos preciosos bytes.

Historias del mundo real

El caso de la sesión de debugging a medianoche

Jasmine, una ingeniera de backend, estaba de guardia. A la 1:30 AM, se disparó una alerta: una mutación crítica de GraphQL estaba fallando en producción. La única pista era una entrada de log que contenía el query exacto enviado por el cliente: una sola línea de 3000 caracteres de texto ininteligible, copiada y pegada de un bundle de JavaScript minificado. Se quedó mirando el muro de texto, ...customer{address{..., tratando de encontrar la parte malformada. Sus ojos se quedaron en blanco. Frustrada, metió la cadena de texto completa en un formateador de GraphQL. Al instante, el query floreció en una estructura de 70 líneas perfectamente indentada. Y ahí estaba, más claro que el agua en la línea 47: un error de tipeo en un nombre de campo crucial, adress en lugar de address. La solución era trivial, pero ni siquiera pudo ver el problema hasta que estuvo formateado.

Lección: La legibilidad es el primer y más importante paso para la depurabilidad. Un formateador convierte una masa de texto impenetrable en algo que un humano puede realmente analizar.

El Pull Request que no se podía mergear

Un pequeño equipo estaba construyendo un nuevo backend de e-commerce con GraphQL. Dos desarrolladores, Liam y Olivia, estaban trabajando en una funcionalidad. Liam configuró su editor para usar una indentación de 4 espacios. Olivia, fan de la indentación de 2 espacios, tenía una configuración diferente. Cuando Liam envió su pull request, Olivia lo revisó, hizo algunos cambios lógicos y subió su commit. El "diff" resultante era un mar de rojo y verde. Casi todas las líneas estaban marcadas como cambiadas, simplemente porque sus editores estaban peleando por el espacio en blanco. Los cambios reales y significativos se perdieron por completo en el ruido. El líder técnico tuvo que pasar una hora desenredando el desastre. Al día siguiente, añadió un formateador de GraphQL automatizado a su hook de pre-commit. Ahora, todo el código se formatea con el mismo estándar exacto antes de que se haga un commit.

Lección: El formateo automatizado elimina las discusiones de estilo y mantiene limpio el historial del control de versiones, centrando las revisiones en lo que importa: la lógica.

El esquema que parecía espagueti

El esquema GraphQL de una startup había crecido orgánicamente durante tres años. Los tipos se añadían donde cupieran, los campos no tenían un orden particular y los comentarios eran esporádicos. Para un nuevo empleado, tratar de entender el modelo de datos de la API era como intentar desenredar un cajón lleno de cables viejos. Decidieron hacer un experimento: pasaron todo el archivo schema.graphql por un formateador. La herramienta no solo indentó todo correctamente, sino que también ordenó alfabéticamente todos los campos dentro de cada tipo. De repente, id era siempre el primer campo. Los campos obsoletos estaban agrupados. Toda la estructura cobró sentido. No solo era más bonito; ahora era una pieza útil de documentación.

Lección: Un esquema bien formateado actúa como documentación viva. Revela la estructura y la intención de tu API, haciéndola más accesible para todos.

Errores y trampas comunes

  • Discutir sobre el estilo. La trampa más grande es perder horas debatiendo sobre tabuladores vs. espacios o dónde debe ir la llave. El valor del formateo es la consistencia. Elige una herramienta popular y dogmática como Prettier, acuerden usarla y sigan adelante.
  • Olvidar formatear antes de hacer commit. Si el formateo es un proceso manual, la gente lo olvidará. Esto lleva a los diffs desordenados que intentabas evitar. Integra el formateo en un hook de pre-commit (usando herramientas como Husky y lint-staged) para que sea automático y sin esfuerzo.
  • Confundir formateo con linting. Un formateador hace que tu código se vea consistente. Un linter (como eslint-plugin-graphql) revisa tu código en busca de posibles bugs o malas prácticas, como usar un campo obsoleto o escribir un query ineficiente. Necesitas ambos. Un formateador limpia la cocina; un linter comprueba si dejaste la estufa encendida.
  • Formatear código generado. Algunos flujos de trabajo generan archivos de esquema o queries de GraphQL desde otra fuente (como un esquema de base de datos o un lenguaje de programación diferente). Formatear el output suele ser una pérdida de tiempo, ya que tus cambios se sobrescribirán la próxima vez que se genere el código. Formatea la fuente en su lugar.
  • Enviar queries con formato "bonito" en producción. Aunque la indentación hermosa es genial para el desarrollo, son bytes desperdiciados en la red. Tu proceso de build debería minificar los queries de GraphQL antes de que se envíen desde tu aplicación cliente al servidor.

Por qué debería estar en tu radar

Deberías empezar a pensar en el formateo de GraphQL en el momento en que un proyecto involucra a más de una persona, o en el momento en que tus queries se vuelven más complejos que un solo campo anidado.

Es una herramienta fundamental para el desarrollo de software profesional que se aplica perfectamente a GraphQL. No se trata de hacer las cosas "bonitas" por el simple hecho de hacerlo. Se trata de:

  • Claridad: Hacer el código más fácil de leer y entender.
  • Mantenibilidad: Hacer el código más fácil de cambiar y depurar.
  • Colaboración: Reducir la fricción entre los miembros del equipo al automatizar las decisiones estilísticas.

Si alguna vez te encuentras mirando un query de GraphQL minificado en un archivo de log, o discutiendo con un compañero de equipo sobre la indentación, es una señal de que necesitas un formateador automático en tu vida.

Para profundizar

Teoría lista. Hora de ensuciarse las manos — 100% en tu navegador.

Probar la herramienta: Formateador GraphQL