API GraphQL con Go: tutorial práctico paso a paso

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: Por qué GraphQL y Go son la pareja ideal

\n

En el desarrollo web moderno, GraphQL se ha convertido en el estándar para crear API flexibles y eficientes. En combinación con el lenguaje Go (Golang), conocido por su rendimiento y simplicidad, obtiene una herramienta poderosa para el desarrollo backend. En este tutorial paso a paso, crearemos una API GraphQL completa en Go desde cero, utilizando la popular biblioteca gqlgen.

\n

Aprenderá a configurar el proyecto, definir el esquema, implementar resolvers y agregar middleware para autenticación. Al final del artículo, tendrá una API funcional lista para integrarse con cualquier frontend.

\n\n

1. Configuración del proyecto e instalación de dependencias

\n

Primero, crearemos un nuevo módulo Go e instalaremos los paquetes necesarios. Asegúrese de tener instalado Go versión 1.18 o superior.

\n
mkdir graphql-go-tutorial\ncd graphql-go-tutorial\ngo mod init graphql-go-tutorial\ngo get github.com/99designs/gqlgen@latest\ngo get github.com/99designs/gqlgen/graphql/introspection@latest
\n

Ahora inicializamos gqlgen en el proyecto. Este comando creará la estructura básica de archivos:

\n
go run github.com/99designs/gqlgen init
\n

Después de la ejecución, verá la siguiente estructura:

\n
    \n
  • graph/ — directorio con archivos de esquema y resolvers
  • \n
  • graph/schema.graphqls — definición del esquema GraphQL
  • \n
  • graph/resolver.go — plantillas para los resolvers
  • \n
  • server.go — punto de entrada de la aplicación
  • \n
  • gqlgen.yml — configuración del generador
  • \n
\n\n

2. Definición del esquema GraphQL

\n

Abriremos el archivo graph/schema.graphqls y definiremos nuestro modelo de datos. Como ejemplo, crearemos un sistema simple de gestión de tareas (Task Manager):

\n
type Task {\n  id: ID!\n  title: String!\n  description: String\n  status: TaskStatus!\n  createdAt: Time!\n}\n\nenum TaskStatus {\n  TODO\n  IN_PROGRESS\n  DONE\n}\n\ntype Query {\n  tasks(status: TaskStatus): [Task!]!\n  task(id: ID!): Task\n}\n\ntype Mutation {\n  createTask(title: String!, description: String): Task!\n  updateTask(id: ID!, title: String, description: String, status: TaskStatus): Task!\n  deleteTask(id: ID!): Boolean!\n}\n\nscalar Time
\n

Después de guardar el esquema, ejecutaremos la generación de código:

\n
go run github.com/99designs/gqlgen generate
\n

Este comando creará los archivos graph/model/models_gen.go con las estructuras Go y actualizará los resolvers.

\n\n

3. Implementación de resolvers y lógica de negocio

\n

Ahora implementaremos la lógica en el archivo graph/schema.resolvers.go. Primero, crearemos un almacenamiento simple en memoria (in-memory store):

\n
// En graph/resolver.go agregamos el almacenamiento\ntype Resolver struct {\n  tasks []*model.Task\n  mu    sync.Mutex\n}\n\nfunc NewResolver() *Resolver {\n  return &Resolver{\n    tasks: make([]*model.Task, 0),\n  }\n}
\n

Ahora implementamos los resolvers para Query y Mutation:

\n
// Query.Task\nfunc (r *queryResolver) Task(ctx context.Context, id string) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  for _, task := range r.tasks {\n    if task.ID == id {\n      return task, nil\n    }\n  }\n  return nil, fmt.Errorf("task not found")\n}\n\n// Mutation.CreateTask\nfunc (r *mutationResolver) CreateTask(ctx context.Context, title string, description *string) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  task := &model.Task{\n    ID:          uuid.New().String(),\n    Title:       title,\n    Description: description,\n    Status:      model.TaskStatusTodo,\n    CreatedAt:   time.Now(),\n  }\n  \n  r.tasks = append(r.tasks, task)\n  return task, nil\n}\n\n// Mutation.UpdateTask\nfunc (r *mutationResolver) UpdateTask(ctx context.Context, id string, title *string, description *string, status *model.TaskStatus) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  for _, task                

Blogs

Book Recommendations