Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🐹
Intermediaire 30 min Go

Go avec GraphQL

Pourquoi Go avec GraphQL ?

GraphQL est un langage de requêtes et une spécification pour API qui permet aux clients d'interroger uniquement les données dont ils ont besoin, ce qui peut améliorer significativement la performance des applications web et mobiles. En tant que développeur Go, le choix de GraphQL peut être bénéfique pour plusieurs raisons :

  • Performance : Les requêtes GraphQL permettent aux clients de récupérer les données nécessaires sans avoir à faire des appels supplémentaires. Cela réduit la quantité de données transmises et améliore ainsi l'expérience utilisateur.

  • Flexibilité : Avec GraphQL, les clients peuvent spécifier exactement ce qu'ils veulent demander dans une requête, ce qui rend l'API plus flexible et évolutrice.

Un cas d'utilisation concret pourrait être un service de gestion des projets où un utilisateur ne souhaite récupérer que les détails essentiels d'un projet particulier, sans avoir à faire appel à d'autres endpoints inutilesment.

Prerequis

  • Connaissance de base du langage Go
  • Familiarité avec les concepts de bases d'API et HTTP
  • Installation de Go : https://golang.org/dl/

Concepts fondamentaux

1. Schéma (Schema)

Le schéma définit l'interface de votre API GraphQL. Il décrit les types disponibles, leurs champs, et comment ils sont liés entre eux.

Exemple de schéma :

type Query {
    project(id: ID!): Project
}

type Mutation {
    createProject(name: String!): Project
}

type Project {
    id: ID!
    name: String!
    tasks: [Task]
}

type Task {
    id: ID!
    title: String!
    completed: Boolean
}

2. Resolveurs (Resolvers)

Les résolveurs sont des fonctions qui exécutent la logique de récupération des données pour chaque champ du schéma.

Exemple de résolveur :

func projectResolver(p graphql.ResolveParams) (interface{}, error) {
    id := p.Args["id"].(string)
    // Logique pour récupérer le projet
    return project, nil
}

3. Contexte (Context)

Le context est utilisé pour passer des données et des informations entre les résolveurs.

Exemple d'utilisation du context :

func createProjectResolver(p graphql.ResolveParams) (interface{}, error) {
    name := p.Args["name"].(string)
    ctx := p.Context.Value("user").(*User)
    // Logique pour créer le projet en utilisant les informations de l'utilisateur
    return project, nil
}

4. Serveur GraphQL

Vous pouvez utiliser une bibliothèque comme graphql-go pour exposer un serveur GraphQL.

Exemple de serveur :

package main

import (
    "net/http"

    "github.com/graphql-go/graphql"
    "github.com/graphql-go/handler"
)

var schema, _ = graphql.NewSchema(graphql.SchemaConfig{
    Query:    queryRoot,
    Mutation: mutationRoot,
})

func main() {
    h := handler.NewDefault()
    h.SetGraphQLHandler(schema)
    
    http.Handle("/graphql", h)
    http.ListenAndServe(":8080", nil)
}

Mise en pratique : projet fil rouge

Étape 1 : Installer les dépendances

go get github.com/graphql-go/graphql
go get github.com/graphql-go/handler

Étape 2 : Définir le schéma et les résolveurs

package main

import (
    "net/http"

    "github.com/graphql-go/graphql"
    "github.com/graphql-go/handler"
)

type Project struct {
    ID      string   `json:"id"`
    Name    string   `json:"name"`
    Tasks   []Task   `json:"tasks"`
}

type Task struct {
    ID        string `json:"id"`
    Title     string `json:"title"`
    Completed bool   `json:"completed"`
}

var projectType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Project",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.String,
        },
        "name": &graphql.Field{
            Type: graphql.String,
        },
        "tasks": &graphql.Field{
            Type: graphql.NewList(taskType),
        },
    },
})

var taskType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Task",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.String,
        },
        "title": &graphql.Field{
            Type: graphql.String,
        },
        "completed": &graphql.Field{
            Type: graphql.Boolean,
        },
    },
})

var queryRoot = graphql.NewObject(graphql.ObjectConfig{
    Name: "Query",
    Fields: graphql.Fields{
        "project": &graphql.Field{
            Type: projectType,
            Args: graphql.FieldConfigArgument{
                "id": &graphql.ArgumentConfig{
                    Type: graphql.String,
                },
            },
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                id := p.Args["id"].(string)
                // Logique pour récupérer le projet
                return Project{ID: id, Name: "Sample Project", Tasks: []Task{}}, nil
            },
        },
    },
})

var mutationRoot = graphql.NewObject(graphql.ObjectConfig{
    Name: "Mutation",
    Fields: graphql.Fields{
        "createProject": &graphql.Field{
            Type: projectType,
            Args: graphql.FieldConfigArgument{
                "name": &graphql.ArgumentConfig{
                    Type: graphql.String,
                },
            },
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                name := p.Args["name"].(string)
                // Logique pour créer le projet
                return Project{ID: "1", Name: name, Tasks: []Task{}}, nil
            },
        },
    },
})

var schema, _ = graphql.NewSchema(graphql.SchemaConfig{
    Query:    queryRoot,
    Mutation: mutationRoot,
})

func main() {
    h := handler.NewDefault()
    h.SetGraphQLHandler(schema)
    
    http.Handle("/graphql", h)
    http.ListenAndServe(":8080", nil)
}

Étape 3 : Exécuter le serveur

go run main.go

Étape 4 : Interroger l'API GraphQL

Ouvrez un navigateur et accédez à http://localhost:8080/graphql. Vous pouvez utiliser les querys et mutations suivantes pour interagir avec l'API :

Query :

query {
    project(id: "1") {
        id
        name
        tasks {
            id
            title
            completed
        }
    }
}

Mutation :

mutation {
    createProject(name: "New Project") {
        id
        name
        tasks {
            id
            title
            completed
        }
    }
}

Erreurs frequentes et debugging

1. panic: runtime error: invalid memory address or nil pointer dereference

Code incorrect :

func resolveProject(p graphql.ResolveParams) (interface{}, error) {
    id := p.Args["id"].(string)
    project := db.FindProject(id) // db is a database connection
    return project, nil
}

Code correct :

func resolveProject(p graphql.ResolveParams) (interface{}, error) {
    id := p.Args["id"].(string)
    project, err := db.FindProject(id) // db is a database connection
    if err != nil {
        return nil, err
    }
    return project, nil
}

2. undefined: graphql.NewSchema

Code incorrect :

schema, _ = graphql.NewSchema(graphql.SchemaConfig{
    Query: queryRoot,
})

Code correct :

import (
    "github.com/graphql-go/graphql"
)

schema, err := graphql.NewSchema(graphql.SchemaConfig{
    Query: queryRoot,
})
if err != nil {
    log.Fatal(err)
}

3. missing field resolver for field 'tasks' in type 'Project'

Code incorrect :

var projectType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Project",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.String,
        },
        "name": &graphql.Field{
            Type: graphql.String,
        },
    },
})

Code correct :

var projectType = graphql.NewObject(graphql.ObjectConfig{
    Name: "Project",
    Fields: graphql.Fields{
        "id": &graphql.Field{
            Type: graphql.String,
        },
        "name": &graphql.Field{
            Type: graphql.String,
        },
        "tasks": &graphql.Field{
            Type: graphql.NewList(taskType),
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                project := p.Source.(Project)
                // Logique pour récupérer les tâches du projet
                return []Task{}, nil
            },
        },
    },
})

Pour aller plus loin

1. Authentification et Autorisation

Ajouter des fonctionnalités d'authentification et d'autorisation pour sécuriser votre API.

2. Pagination et Filtrage

Ajouter des capacités de pagination et de filtrage pour permettre aux clients de récupérer des données plus complexes et détaillées.

3. Subscriptions

Permettre aux clients d'écouter les mises à jour en temps réel avec GraphQL Subscriptions.

Défi pratique

Créez une API de gestion des utilisateurs avec des fonctionnalités telles que l'inscription, la connexion et la récupération des profils d'utilisateurs. Implémentez les fonctionnalités CRUD pour les utilisateurs.

  • Défi : Créer une API GraphQL pour gérer les utilisateurs

Besoin d'aide sur Go ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Qu'est-ce que GraphQL avec Go?
GraphQL est une spécification d'API qui permet aux clients d'interroger exactement les données dont ils ont besoin, en un seul appel réseau. Avec Go, vous pouvez utiliser des bibliothèques comme 'graphql-go' pour implémenter un serveur GraphQL.
Comment installer graphql-go?
Pour installer graphql-go dans votre projet Go, utilisez la commande suivante : go get github.com/graphql-go/graphql
Quelles sont les avantages de utiliser GraphQL avec Go?
GraphQL vous permet d'optimiser vos appels API en demandant uniquement ce dont vous avez besoin. Cela réduit le temps de réponse et améliore l'efficacité du réseau. De plus, Go est connu pour son haut rendement et sa sécurité, ce qui rend GraphQL avec Go une combinaison idéale pour les applications critiques.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.