Lección 2 de 20 · Lectura y práctica
Definir un Esquema GraphQL Básico con Tipos
Concepto claveUn 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.
Del concepto a la práctica
Taller de esta lección
Un esquema útil expresa restricciones que el cliente puede comprobar antes de ejecutar la operación. La diferencia entre String, String!, [Item] y [Item!]! cambia qué respuestas son válidas, así que la nulabilidad debe representar una decisión de dominio, no una decoración.
Ejemplo resuelto
Para una agenda de sesiones:
type Session { id: ID!, topic: String!, seats: Int!, tags: [String!]! }
type Query { session(id: ID!): Session }Una sesión siempre tiene identificador, tema, cupos y una lista, aunque la lista esté vacía. session puede ser nula porque el identificador podría no existir.
Enumera las entidades que el cliente necesita consultar.
Marca como obligatorios solo los campos garantizados por los datos.
Define argumentos con nombres y tipos explícitos.
Escribe una consulta válida y otra que el esquema deba rechazar.
Error frecuente: confundir [String]!, que permite elementos nulos, con una lista de etiquetas siempre presentes. Corrección: usa [String!]! si tanto la lista como cada etiqueta deben existir.
Pruébalo
Añade level: Int! y prueba una sesión con level: 2.
Comprueba tu resultado
La consulta devuelve tags: [] para una sesión sin etiquetas; un resolver que omite topic falla durante la ejecución; una variable Int que contiene texto falla al convertir los inputs. No es el mismo momento de error.
Tres resultados que no debes confundir
Seleccionar solo id sin topic es una consulta válida: no es obligatorio pedir todos los campos no nulos. Pedir un campo inexistente falla antes de ejecutar resolvers. Si el resolver devuelve topic=null para un campo String!, GraphQL agrega errors y propaga null hasta el padre nullable, aquí session. En cambio tags=[] cumple [String!]!: lista obligatoria no significa lista no vacía. Una variable para un argumento Int debe ser un número entero válido; la conversión de variables ocurre antes de invocar el campo.

Mapa de prácticaEl navegador envía una solicitud a la API. El servidor valida la operación y consulta los datos; después devuelve una respuesta que el navegador puede mostrar. La base de datos se comunica con el servidor y no directamente con el navegador.
Ver la infografía en tamaño completo ↗Fuentes para profundizar
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.
Pistas
- 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.
Sigue con GraphQL Profesional con Next.js y Apollo Server: APIs Tipadas y Suscripciones
Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.
Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.