Definir un Esquema GraphQL Básico con Tipos

Lectura
20 min~5 min lectura

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:

  1. Crea un archivo schema.graphql en la carpeta lib/graphql de tu proyecto Next.js.
  2. 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
    }
  3. Observa que ! indica que un campo es no-nulo (obligatorio), y [] denota una lista. El tipo Query es especial: define las consultas que los clientes pueden realizar.
  4. 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, en nombre: String vs nombre: String!, el primero acepta null, el segundo no.
  • Definir tipos circulares sin límites: En relaciones como la de Curso e Instructor, 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 ID para identificadores únicos, no String. Esto ayuda a GraphQL a optimizar el caching y la validación. Por ejemplo, id: ID! es mejor que id: 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 Query con 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:

  1. Crea un nuevo proyecto Next.js o usa uno existente. En la carpeta lib/graphql, crea un archivo llamado schema.graphql.
  2. Define un tipo Tarea con los siguientes campos: id (ID, no nulo), titulo (String, no nulo), descripcion (String, puede ser nulo), completada (Boolean, no nulo, valor por defecto false), y fechaCreacion (String, no nulo).
  3. Define un tipo Query con dos consultas: tareas que devuelva una lista no nula de tareas no nulas, y tarea que acepte un argumento id de tipo ID no nulo y devuelva una tarea (puede ser nula si no se encuentra).
  4. Define un tipo Mutation con al menos una mutación: crearTarea que acepte argumentos para titulo y descripcion (ambos Strings, titulo no nulo) y devuelva la tarea creada.
  5. 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.