Concepto clave
Un esquema GraphQL es la definición formal de tu API. Piensa en él como el contrato entre el cliente y el servidor: especifica qué datos se pueden consultar, qué mutaciones se pueden realizar y qué suscripciones están disponibles. A diferencia de REST, donde tienes múltiples endpoints, GraphQL tiene un único endpoint y el esquema define todas las operaciones posibles.
Los tipos GraphQL son los bloques fundamentales del esquema. Cada tipo define la estructura de un objeto, incluyendo sus campos y el tipo de dato de cada campo. Los tipos escalares básicos (como String, Int, Float, Boolean, e ID) representan valores atómicos, mientras que los tipos de objeto agrupan campos relacionados. Por ejemplo, en una aplicación de e-commerce, podrías tener un tipo Producto con campos como id (ID), nombre (String), y precio (Float).
Un esquema bien definido es como el plano de un edificio: sin él, cada desarrollador construiría de forma diferente, llevando a inconsistencias y errores.
Cómo funciona en la práctica
Para definir un esquema básico en GraphQL con Apollo Server y Next.js, sigamos estos pasos:
- Crea un archivo
schema.graphqlen la carpetalib/graphqlde tu proyecto Next.js. - Define tipos usando la sintaxis SDL (Schema Definition Language). Por ejemplo:
type Producto { id: ID! nombre: String! precio: Float! stock: Int } type Query { productos: [Producto!]! producto(id: ID!): Producto } - Observa que
!indica que un campo es no-nulo (obligatorio), y[]denota una lista. El tipoQueryes especial: define las consultas que los clientes pueden realizar. - Integra este esquema en Apollo Server en tu API route de Next.js, importándolo y pasándolo a la configuración del servidor.
Este enfoque asegura que tu API esté tipada desde el inicio, reduciendo errores en tiempo de ejecución.
Caso de estudio
Imagina que estás construyendo una API para una plataforma de cursos en línea. Tu esquema podría incluir tipos como Curso, Instructor, y Estudiante. Aquí un ejemplo concreto:
type Curso {
id: ID!
titulo: String!
descripcion: String
duracionHoras: Int!
instructor: Instructor!
estudiantesInscritos: [Estudiante!]
}
type Instructor {
id: ID!
nombre: String!
especialidad: String!
cursosDictados: [Curso!]!
}
type Query {
cursos: [Curso!]!
cursoPorId(id: ID!): Curso
instructores: [Instructor!]!
}Este esquema permite consultas como obtener todos los cursos con sus instructores, o un curso específico por ID. Nota cómo los tipos se relacionan: Curso tiene un campo instructor de tipo Instructor, y Instructor tiene un campo cursosDictados que es una lista de Curso. Esto crea una estructura de datos coherente y reutilizable.
Errores comunes
- Olvidar los signos de exclamación para campos obligatorios: Si un campo debe siempre devolver un valor, usa
!. Sin él, GraphQL permitirá valores nulos, lo que puede causar errores en el cliente. Por ejemplo, ennombre: Stringvsnombre: String!, el primero acepta null, el segundo no. - Definir tipos circulares sin límites: En relaciones como la de
CursoeInstructor, asegúrate de que las listas no sean infinitas. En la práctica, limita la profundidad de las consultas o usa paginación para evitar sobrecargar el servidor. - No usar tipos escalares apropiados: Usa
IDpara identificadores únicos, noString. Esto ayuda a GraphQL a optimizar el caching y la validación. Por ejemplo,id: ID!es mejor queid: String!. - Ignorar la nulabilidad en listas: Una lista como
[Producto]puede ser null o contener elementos null. Para evitar esto, usa[Producto!]!que asegura que la lista no sea null y que ningún elemento sea null. - Definir esquemas demasiado complejos desde el inicio: Comienza con tipos básicos y expande según las necesidades. Un esquema sobrecargado puede ser difícil de mantener y ralentizar el desarrollo.
Checklist de dominio
- He definido al menos tres tipos de objeto en mi esquema GraphQL, usando SDL en un archivo
.graphql. - He incluido un tipo
Querycon al menos dos consultas diferentes que devuelven datos de mis tipos. - He usado tipos escalares correctos (String, Int, Float, Boolean, ID) para los campos, aplicando no-nulabilidad (
!) donde sea necesario. - He establecido relaciones entre tipos, como un campo en un tipo que referencia otro tipo, manejando listas con sintaxis apropiada (e.g.,
[Tipo!]!). - He integrado mi esquema en Apollo Server dentro de un proyecto Next.js, verificando que se pueda ejecutar una consulta básica.
- He evitado tipos circulares infinitos al limitar la profundidad de las relaciones en las definiciones.
- He revisado mi esquema para asegurar que sea coherente con los requisitos del negocio, como campos obligatorios para datos críticos.
Definir un esquema GraphQL para una app de tareas
En este ejercicio, crearás un esquema GraphQL básico para una aplicación de gestión de tareas (todo list). Sigue estos pasos:
- Crea un nuevo proyecto Next.js o usa uno existente. En la carpeta
lib/graphql, crea un archivo llamadoschema.graphql. - Define un tipo
Tareacon los siguientes campos:id(ID, no nulo),titulo(String, no nulo),descripcion(String, puede ser nulo),completada(Boolean, no nulo, valor por defecto false), yfechaCreacion(String, no nulo). - Define un tipo
Querycon dos consultas:tareasque devuelva una lista no nula de tareas no nulas, ytareaque acepte un argumentoidde tipo ID no nulo y devuelva una tarea (puede ser nula si no se encuentra). - Define un tipo
Mutationcon al menos una mutación:crearTareaque acepte argumentos paratituloydescripcion(ambos Strings, titulo no nulo) y devuelva la tarea creada. - Integra este esquema en un API route de Next.js usando Apollo Server. Prueba ejecutar una consulta simple en GraphQL Playground o Apollo Studio para verificar que funciona.
- Recuerda que en SDL, los argumentos en mutaciones se definen entre paréntesis, por ejemplo: crearTarea(titulo: String!, descripcion: String): Tarea
- Usa el tipo ID para el campo id, no String, para aprovechar las optimizaciones de GraphQL.
- Asegúrate de que las listas en GraphQL usen la sintaxis correcta: [Tarea!]! significa una lista no nula que no contiene elementos nulos.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.