Definir tus propios tipos de datos es uno de los pasos más importantes para construir una API robusta con GraphQL. Cuando trabajas con entidades como productos, usuarios u órdenes, necesitas ir más allá de los tipos primitivos y crear estructuras que representen fielmente tu modelo de datos. Aquí se explica cómo lograrlo usando la instrucción type y cómo funciona la selección de fields en las consultas.
¿Cómo crear un tipo personalizado con type en GraphQL?
Para representar una entidad compleja, como un producto, se utiliza la palabra clave type seguida del nombre del tipo. Es fundamental recordar que existen palabras reservadas que no puedes usar como nombre: Query, Mutation y los tipos primitivos del sistema como String, Int, Float, Boolean e ID [01:00].
Un ejemplo de definición de tipo para un producto luce así:
graphql
type Product {
id: ID!
name: String!
price: Float!
description: String!
image: String!
created_at: String!
}
- Cada campo tiene un nombre y un tipo de dato asignado.
- El símbolo
! indica que el campo no puede ser nulo, es decir, es obligatorio.
- El tipo
ID es especial en GraphQL y se usa para identificadores únicos.
- El tipo
Float permite manejar números con decimales, ideal para precios.
¿Qué pasa si usas un tipo que no existe en el sistema?
Un detalle importante surge al intentar usar un tipo como Date para la fecha de creación. GraphQL no incluye un tipo Date nativo dentro de su sistema de tipos [02:12]. Si lo defines así, al ejecutar el servidor verás un error indicando que el tipo no fue encontrado. La solución inmediata es usar String y enviar la fecha en formato ISO con toISOString(). Más adelante es posible extender el sistema de tipos, pero por defecto debes ceñirte a los tipos disponibles.
¿Cómo resolver una query que retorna un objeto personalizado?
Una vez definido el tipo, el siguiente paso es crear una query que lo retorne y su correspondiente resolver [03:05].
graphql
type Query {
getProduct: Product
}
El resolver debe devolver un objeto que cumpla con la estructura definida en el tipo:
javascript
const resolvers = {
Query: {
getProduct: () => {
return {
id: '12',
name: 'Producto 1',
price: 100.00,
description: 'Una descripción',
image: 'https://example.com/image.png',
created_at: new Date().toISOString()
}
}
}
}
Cuando el tipo retornado es un objeto y no un escalar, GraphQL exige que selecciones los campos que deseas recibir. No basta con llamar a getProduct; debes indicar explícitamente qué fields necesitas [04:15].
¿Cómo seleccionar campos específicos en una consulta?
En el playground, la consulta se escribe así:
graphql
{
getProduct {
id
name
description
}
}
- Solo recibes los campos que solicitas, nada más.
- Puedes cambiar el orden de los campos y la respuesta respetará ese orden.
- Si omites las llaves con los campos, GraphQL lanzará un error indicando que debes hacer una selección.
Esta capacidad de pedir únicamente lo que necesitas es una de las ventajas fundamentales de GraphQL frente a REST, donde normalmente recibes todos los campos sin importar si los usas o no.
¿Qué sucede cuando hay un error de tipeo en el resolver?
Un caso práctico y revelador ocurre cuando el nombre de un campo en el resolver no coincide con la definición del tipo [05:30]. Por ejemplo, si en el tipo defines created_at pero en el resolver escribes create_at (sin la d), al solicitar ese campo en la consulta obtendrás un error: el campo no está siendo resuelto.
Esto es especialmente útil porque actúa como una validación automática. El frontend puede detectar que el backend no está retornando un campo esperado, lo que facilita la depuración y asegura que el contrato entre ambas partes se respete gracias al tipado estricto de GraphQL.
Puedes verificar la estructura completa de tu tipo en la sección de documentación del playground, donde se listan todos los campos disponibles y si son obligatorios [05:05].
Dominar la creación de tipos personalizados y la selección de fields te prepara para integrar datos reales desde una base de datos. ¿Has encontrado errores similares de tipeo al definir tus resolvers? Comparte tu experiencia en los comentarios.