Introduction : Pourquoi GraphQL et Go sont-ils le duo idéal ?
Le développement web moderne nécessite des API flexibles et performantes. L'API REST, malgré sa popularité, souffre souvent de surcharge de données (over-fetching) ou de leur insuffisance (under-fetching). GraphQL résout ce problème en permettant au client de demander exactement ce dont il a besoin. Et Go (Golang), avec sa vitesse, sa simplicité et son support intégré de la concurrence, devient le langage idéal pour créer des serveurs GraphQL.
Dans ce tutoriel, nous allons créer pas à pas une API GraphQL complète en Go. Vous apprendrez à configurer le serveur, définir le schéma, écrire les résolveurs, ainsi qu'à implémenter les requêtes (queries) et les mutations (mutations). À la fin de l'article, vous disposerez d'une API fonctionnelle, prête à être intégrée avec n'importe quel client.
Étape 1 : Configuration du projet et installation des dépendances
Pour commencer, créons un nouveau module Go et installons les bibliothèques nécessaires. Nous utiliserons deux bibliothèques GraphQL populaires : graphql-go et graphql-go-handler.
1.1. Initialisation du module
go mod init graphql-tutorial1.2. Installation des bibliothèques
go get github.com/graphql-go/graphqlgo get github.com/graphql-go/handlerCes bibliothèques fournissent tous les outils nécessaires pour travailler avec les schémas, les types et les résolveurs.
Étape 2 : Création du schéma GraphQL de base
Le schéma est le cœur de l'API GraphQL. Il définit quelles données peuvent être obtenues et quelles actions peuvent être effectuées. Commençons par un modèle simple "Utilisateur".
2.1. Définition du type User
import "github.com/graphql-go/graphql"
var userType = graphql.NewObject(graphql.ObjectConfig{ Name: "User", Fields: graphql.Fields{ "id": &graphql.Field{ Type: graphql.Int, }, "name": &graphql.Field{ Type: graphql.String, }, "email": &graphql.Field{ Type: graphql.String, }, },})2.2. Création de la requête racine
var rootQuery = graphql.NewObject(graphql.ObjectConfig{ Name: "RootQuery", Fields: graphql.Fields{ "user": &graphql.Field{ Type: userType, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.Int, }, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { id, _ := p.Args["id"].(int) // Ici se trouvera la logique pour récupérer l'utilisateur depuis la base de données return getUserByID(id), nil }, }, },})2.3. Regroupement dans le schéma
var schema, _ = graphql.NewSchema(graphql.SchemaConfig{ Query: rootQuery,})Étape 3 : Implémentation des résolveurs et du serveur
Maintenant que le schéma est prêt, il faut écrire les résolveurs — les fonctions qui renvoient effectivement les données. Pour simplifier, utilisons un stockage en mémoire (in-memory).
3.1. Stockage en mémoire (in-memory)
type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"`}
var users = []User{ {ID: 1, Name: "Ivan Petrov", Email: "ivan@example.com"}, {ID: 2, Name: "Maria Sidorova", Email: "maria@example.com"},}
func getUserByID(id int) *User { for _, u := range users { if u.ID == id { return &u } } return nil}3.2. Lancement du serveur HTTP
package main
import ( "fmt" "log" "net/http"
"github.com/graphql-go/handler")
func main() { h := handler.New(&handler.Config{ Schema: &schema, Pretty: true, GraphiQL: true, // Active l'IDE intégré })
http.Handle("/graphql", h) fmt.Println("Serveur démarré sur")