API GraphQL avec Go : tutoriel pratique étape par étape

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : Pourquoi GraphQL et Go forment un duo idéal

\n

Dans le développement web moderne, GraphQL est devenu une norme pour créer des API flexibles et efficaces. Associé au langage Go (Golang), réputé pour ses performances et sa simplicité, vous obtenez un outil puissant pour le développement backend. Dans ce tutoriel étape par étape, nous allons créer une API GraphQL complète en Go à partir de zéro, en utilisant la bibliothèque populaire gqlgen.

\n

Vous apprendrez à configurer le projet, définir le schéma, implémenter les résolveurs et ajouter du middleware pour l'authentification. À la fin de l'article, vous disposerez d'une API fonctionnelle, prête à être intégrée avec n'importe quel frontend.

\n\n

1. Configuration du projet et installation des dépendances

\n

Tout d'abord, créons un nouveau module Go et installons les paquets nécessaires. Assurez-vous d'avoir installé Go version 1.18 ou supérieure.

\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

Maintenant, initialisons gqlgen dans le projet. Cette commande créera une structure de fichiers de base :

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

Après exécution, vous verrez la structure suivante :

\n
    \n
  • graph/ — répertoire contenant les fichiers de schéma et de résolveurs
  • \n
  • graph/schema.graphqls — définition du schéma GraphQL
  • \n
  • graph/resolver.go — ébauches pour les résolveurs
  • \n
  • server.go — point d'entrée de l'application
  • \n
  • gqlgen.yml — configuration du générateur
  • \n
\n\n

2. Définition du schéma GraphQL

\n

Ouvrons le fichier graph/schema.graphqls et définissons notre modèle de données. Pour l'exemple, créons un système simple de gestion des tâches (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

Après avoir enregistré le schéma, lançons la génération de code :

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

Cette commande créera le fichier graph/model/models_gen.go avec les structures Go et mettra à jour les résolveurs.

\n\n

3. Implémentation des résolveurs et de la logique métier

\n

Implémentons maintenant la logique dans le fichier graph/schema.resolvers.go. Commençons par créer un simple stockage en mémoire (in-memory store) :

\n
// Dans graph/resolver.go, ajoutons le stockage\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

Implémentons maintenant les résolveurs pour Query et 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