Buenas prácticas de GraphQL
GraphQL es lo suficientemente maduro, y lleva entre nosotros el tiempo suficiente, como para que la comunidad haya publicado muchos artículos compartiendo buenas prácticas. Estas guías cubren prácticamente todos los aspectos de GraphQL, incluyendo diseño del esquema, convenciones de nomenclatura, gestión de la seguridad y proporcionar errores significativos, entre otros.
Estas son algunas de las guías más convincentes que existen sobre buenas prácticas en GraphQL.
Buenas prácticas en graphql.org
El sitio oficial de GraphQL ofrece una introducción general a buenas prácticas en GraphQL.
Estos puntos cubren principalmente preocupaciones de alto nivel, como:
- Cuál es la mejor forma de paginar los resultados
- Dónde se sitúa la capa GraphQL dentro de la arquitectura
- Cómo usar la interfaz Node para la global object identification
- Cómo cachear resultados
- Muchos otros

Recomendaciones de Lee Byron
No mucho después de presentar GraphQL al mundo, el creador de GraphQL Lee Byron publicó el artículo Lessons From 4 Years of GraphQL, describiendo cómo deberíamos intentar conceptualmente trabajar con GraphQL:
- Los nombres importan
- Piensa en grafos, no en endpoints
- Describe los datos, no la vista
- GraphQL es una interfaz fina
- Oculta los detalles de implementación
También detalla varios principios y lecciones valiosos que aprendió mientras usaba GraphQL en Facebook.
GraphQL Rules
GraphQL Rules es un sitio especialmente dedicado a presentar buenas prácticas del día a día para trabajar con GraphQL, principalmente sobre el diseño del esquema GraphQL.
Este recurso es muy completo. Recopila la información de unos pocos recursos excepcionales que existen (como el artículo Designing GraphQL Mutations y el tutorial de Shopify Designing a GraphQL API) y los presenta todos juntos de forma concisa.
Las reglas descritas incluyen:
- Reglas de nomenclatura
- Usa
camelCasepara los campos y argumentos de GraphQL. - Usa
UpperCamelCasepara los tipos GraphQL. - Usa
CAPITALIZED_WITH_UNDERSCORESpara nombrar los tipos ENUM.
- Usa
- Reglas de tipos
- Usa tipos escalares personalizados si quieres declarar campos o argumentos con un valor semántico específico.
- Usa Enum para campos que contienen un conjunto específico de valores.
- Reglas de campos (Output)
- Usa nombres semánticos para los campos y evita filtrar detalles de implementación en los nombres de los campos.
- Usa campo
Non-Nullsi el campo siempre tendrá un valor de campo dado. - Agrupa tantos campos relacionados como sea posible en un Object type personalizado.
- Reglas de argumentos (Input)
- Agrupa argumentos acoplados en el nuevo input-type.
- Usa tipos escalares estrictos para los argumentos, p. ej.
DateTimeen lugar deString. - Marca los argumentos como
required, si son requeridos para la ejecución de la consulta.
- Reglas de listas
- Para filtrar las listas, usa el argumento
filter, que contiene todos los filtros disponibles. - Usa el argumento
sortde tipoEnumo[Enum!]para ordenar listados. - Usa
limitcon valor por defecto yskippara limitar el número de elementos devueltos en la lista. - Usa los argumentos
page,perPagepara paginación y devuelve un output type conitems(array de elementos) ypageInfo(meta-datos). - Para listas infinitas (infinite scroll) usa Relay Cursor Connections Specification.
- Para filtrar las listas, usa el argumento
- Reglas de mutaciones
- Usa Namespace-types para agrupar mutaciones dentro de un único recurso.
- Ve más allá de CRUD – crea pequeñas mutaciones para diferentes operaciones de negocio sobre recursos.
- Considera la capacidad de realizar mutaciones en múltiples elementos (cambios por lotes del mismo tipo).
- Las mutaciones deben describir claramente todos los argumentos obligatorios, no debe haber opciones either-either.
- En las mutaciones, pon todas las variables en un único argumento input.
- Cada mutación debe tener un payload type único.
Buenas prácticas para resolvers
El artículo GraphQL Resolvers: Best Practices describe cómo crear mejor los resolvers de campo. Aunque está dirigido a servidores Node.js (la infraestructura de PayPal está basada en Express), varias de sus lecciones también pueden aplicarse a otras tecnologías, incluyendo PHP.
Las conclusiones principales son:
- Obtener y pasar datos de padre a hijo debe usarse con moderación.
- Usa librerías como dataloader para deduplicar peticiones descendentes.
- Sé consciente de cualquier presión que estés causando en tus fuentes de datos.
- No mutes "context". Asegura código consistente y con menos errores.
- Escribe resolvers que sean legibles, mantenibles y testeables. No demasiado astutos.
- Haz tus resolvers lo más finos posible. Extrae la lógica de obtención de datos a funciones async reutilizables.
OWASP - GraphQL Cheat Sheet
OWASP (Open Web Application Security Project) es una fundación sin ánimo de lucro que trabaja para mejorar la seguridad del software. Realiza investigaciones sobre cómo diferentes tecnologías son vulnerables a exploits, y describe a fondo soluciones a los problemas de seguridad, facilitando a los desarrolladores prevenir ataques.
OWASP ha publicado el GraphQL Cheat Sheet, explicando cuáles son los ataques más comunes y los mayores problemas de seguridad en GraphQL, y cómo abordarlos.
Los ataques comunes a GraphQL son:
- Injection - esto normalmente incluye pero no se limita a:
- SQL y NoSQL injection
- OS Command injection
- SSRF y CRLF injection/Request Smuggling
- DoS (Denial of Service)
- Abuso de autorización rota: ya sea acceso impropio o excesivo, incluyendo IDOR
- Batching Attacks, un método de ataque de fuerza bruta específico de GraphQL
- Abuso de configuraciones por defecto inseguras
OWASP entonces proporciona recomendaciones sobre cómo evitar cada uno de estos.
Buenas prácticas con consultas GraphQL
El equipo de Apollo publicó las GraphQL query best practices, dando perspectivas prácticas sobre formas prácticas de componer la consulta GraphQL.
Por ejemplo, estas dos consultas logran el mismo objetivo, pero como la primera tiene un nombre de operación, es más comprensible y útil al depurar:
# Recomendado
query GetBooks {
books {
title
}
}
# No recomendado
query {
books {
title
}
}Sus sugerencias incluyen:
- Nombra todas las operaciones
- Usa variables para proporcionar argumentos GraphQL
- Consulta solo los datos que necesitas, donde los necesitas
- Usa fragments para encapsular conjuntos relacionados de campos
- Consulta datos globales y datos específicos de usuario por separado
Aprovechar el one graph
También del equipo de Apollo es el sitio Principled GraphQL que explica que GraphQL no es solo una especificación sino, posiblemente más importante, una interfaz para interactuar con el "grafo" de datos de nuestra empresa.
Mediante una lista de 10 principios, este sitio describe cómo sacar el máximo provecho del único grafo:
- One Graph: tu empresa debe tener un grafo unificado, en lugar de múltiples grafos creados por cada equipo.
- Federated Implementation: aunque solo hay un grafo, la implementación de ese grafo debe estar federada entre múltiples equipos.
- Track the Schema in a Registry: debe haber una única fuente de verdad para registrar y rastrear el grafo.
- Abstract, Demand-Oriented Schema: el esquema debe actuar como una capa de abstracción que proporciona flexibilidad a los consumidores mientras oculta los detalles de implementación del servicio.
- Use an Agile Approach to Schema Development: el esquema debe construirse incrementalmente basándose en requisitos reales y evolucionar suavemente con el tiempo.
- Iteratively Improve Performance: la gestión del rendimiento debe ser un proceso continuo, basado en datos, adaptándose suavemente a las cargas de consultas y a las implementaciones de servicios cambiantes.
- Use Graph Metadata to Empower Developers: los desarrolladores deben estar equipados con un rico conocimiento del grafo durante todo el proceso de desarrollo.
- Access and Demand Control: concede acceso al grafo por cliente, y gestiona qué y cómo pueden acceder los clientes.
- Structured Logging: captura logs estructurados de todas las operaciones del grafo y aprovéchalos como la herramienta principal para entender el uso del grafo.
- Separate the GraphQL Layer from the Service Layer: adopta una arquitectura por capas con la funcionalidad del grafo dividida en una capa separada en lugar de horneada en cada servicio.