Comment construire une API GraphQL ?

Qu'est-ce que GraphQL ?

Ces dernières années, GraphQL est devenu un choix populaire pour la création d’API complexes. En effet, il élimine certaines des limites des API REST traditionnelles et rend votre API plus flexible et plus efficace.

Dans cet article, nous parlerons de GraphQL, de ses avantages et de ses inconvénients, de la terminologie clé de GraphQL et nous comparerons les API GraphQL aux API REST. De plus, nous vous apprendrons à construire votre propre API GraphQL sur Back4app et à vous y connecter à partir d’un frontend Next.js.

Introduction à GraphQL

GraphQL est un langage de requête et un moteur d’exécution côté serveur pour le développement d’interfaces de programmation d’applications (API). Avec GraphQL, les clients peuvent spécifier exactement les données dont ils ont besoin à partir de l’API, plutôt que de compter sur le backend pour fournir un ensemble fixe de données.

GraphQL est une approche moderne et efficace pour construire des API rapides et flexibles. Il dispose d’un système de types intégré et repose sur un schéma fortement typé qui définit les données disponibles par l’intermédiaire de l’API. Elle prend en charge les mises à jour et les abonnements en temps réel et permet aux développeurs de récupérer des données à partir de sources multiples. En outre, il facilite l’évolution des API en donnant aux développeurs la possibilité de supprimer des champs sans incidence sur les requêtes ou les mutations existantes.

GraphQL peut être utilisé dès le début d’un projet ou intégré à une API existante. Certaines entreprises le combinent également avec REST et le migrent ensuite étape par étape.

Il a été développé en interne par Facebook en 2012, puis ouvert à tous en 2015. GraphQL a gagné en popularité avec l’essor des applications à page unique (SPA) et des applications mobiles. Depuis sa sortie, il a été adopté par de nombreux géants de la technologie tels que GitHub, Airbnb, Pinterest et Shopify.

GraphQL vs REST

GraphQL et REST sont deux approches populaires pour la création d’API web.

REST (Representational State Transfer) est un style d’architecture logicielle qui décrit la structure du web. Il a été introduit en 2000 et est devenu la norme de facto pour la création d’API web depuis plus d’une décennie. Il utilise des méthodes HTTP telles que GET, POST, PUT, PATCH et DELETE pour manipuler les ressources. Chaque ressource est hébergée à son point de terminaison (voir l’image ci-dessous) et chaque fois que nous demandons une ressource, l’ensemble des données est renvoyé.

Cette architecture pose deux problèmes. Le premier est le manque de données (trop peu de données) et l’excès de données (trop de données). De plus, les API REST ne nous permettent pas de nous abonner aux changements de données.

C’est là qu’intervient GraphQL. GraphQL a un point de terminaison unique et nous permet d’interroger des données à partir de plusieurs sources de données en une seule requête. Il nous permet de définir exactement les données dont nous avons besoin. En outre, GraphQL nous permet de nous abonner aux modifications de données sans interroger le serveur. Il rend notre API plus prévisible et auto-documentée.

En fin de compte, le choix entre GraphQL et REST dépendra des exigences spécifiques de votre projet. Même si GraphQL est excellent, il risque d’introduire trop de complexité pour les projets simples.

API REST vs API GraphQL

Termes courants de GraphQL

Examinons quelques-uns des termes courants que vous pouvez rencontrer lorsque vous travaillez avec GraphQL.

Type

GraphQL possède un système de types et est fortement typé. Il est livré avec des types scalaires intégrés tels que Int, Float, String et Boolean, mais il permet également de définir des types personnalisés.

Un type personnalisé peut être défini comme suit :

type User {
    username: String!
    password: String!
    friends: [User!]
}

Schéma

Un schéma est une description des données disponibles via une API GraphQL. Il comprend les types d’objets, leurs champs et les types de données associés, les relations, les requêtes, les mutations, etc. Un schéma est généralement défini à l’aide du langage de définition de schéma (SDL).

Un exemple de schéma

Résolveur

Un résolveur est une fonction qui récupère les données d’un champ particulier dans une requête GraphQL. Les fonctions de résolveur sont chargées de récupérer les données d’une source de données et de les renvoyer dans le format attendu.

Demande de renseignements

Une requête est une demande de données en lecture seule provenant d’une API GraphQL. Vous pouvez considérer les requêtes comme des demandes GET dans l’API REST.

Exemple :

query GetUser {
    user(id: "Wfx8o2AZrE") {
        id
        username
        fullName
    }
}

Cette requête renvoie la liste de tous les utilisateurs.

Mutation

Une mutation est une demande de manipulation des données dans une API GraphQL. Vous pouvez considérer les mutations comme des demandes POST/PUT/PATCH/DELETE dans l’API REST. Les mutations peuvent également définir les données renvoyées.

Exemple :

mutation CreateAuthor {
  createAuthor(input: {fields: {firstName: "William", lastName: "Shakespeare"}}) {
    author {
      id
      createdAt
    }
  }
}

Cette mutation crée un nouvel auteur et renvoie l’identifiant et la date de création de l’auteur.

Abonnement

Un abonnement est une demande de mise à jour en temps réel d’une API GraphQL. Les abonnements permettent aux clients de recevoir des mises à jour dès qu’elles sont disponibles, sans avoir à interroger le serveur.

Exemple :

subscription OnPostCreate($postID: ID!) {
  userAdded(postID: $postID) {
    id
    user
    content
  }
}

Cet abonnement est appelé lorsqu’un nouveau message est créé.

Comment fonctionne GraphQL ?

Pour mettre en œuvre une API GraphQL, vous devez suivre les étapes suivantes :

  1. Décrivez vos données à l’aide d’un schéma
  2. Connecter les résolveurs aux sources de données
  3. Rédiger des requêtes et des mutations
  4. Obtenir des résultats prévisibles

En utilisant Back4app ou un service similaire, la plupart de ce travail sera abstrait. Au fur et à mesure que vous créez les modèles de base de données, Back4app génère automatiquement le schéma GraphQL et la documentation. Plus d’informations à ce sujet dans la partie pratique du tutoriel.

Quels sont les avantages de GraphQL ?

GraphQL est facile à apprendre, les utilisateurs peuvent agréger des données provenant de sources multiples et il s’agit d’un langage moderne pour votre API.

Schéma

L’API GraphQL est basée sur un schéma fortement typé. Cela vous permet de détecter les erreurs de type et les bogues au moment de la compilation plutôt qu’au moment de l’exécution. En outre, les API GraphQL sont introspectives, ce qui signifie qu’elles peuvent fournir des informations sur elles-mêmes sans s’appuyer sur une documentation externe.

Extraction souple et efficace des données

Les API GraphQL sont extrêmement flexibles car elles permettent aux clients de spécifier exactement ce dont ils ont besoin. Cela résout le problème de l’insuffisance et de l’excès d’extraction et réduit le nombre de demandes d’API. La réduction du nombre de demandes d’API se traduit par une amélioration des performances.

Mises à jour de l’API

Avec GraphQL, vous pouvez intégrer en toute transparence de nouveaux champs et types sans affecter les requêtes actuelles. Les champs obsolètes ou dépassés peuvent également être dissimulés aux outils. Les API GraphQL permettent aux applications d’accéder en permanence à de nouvelles fonctionnalités et encouragent le développement d’un code serveur plus propre et plus durable.

Une seule source de vérité

Un schéma GraphQL constitue une source unique de vérité dans une application GraphQL. Il offre à une organisation un moyen simple de gérer l’ensemble de son API.

Extensions GraphQL

GraphQL est soutenu par une vaste communauté de développeurs GraphQL et s’accompagne de nombreuses extensions open-source. Ces extensions simplifient certaines tâches courantes de l’API, telles que la pagination, la mise en cache, le contrôle des performances, etc.

Quels sont les inconvénients de GraphQL ?

Complexité

GraphQL transfère une grande partie du travail d’interrogation des données du côté du serveur, ce qui rend les backends plus complexes. En outre, le langage d’interrogation et les définitions de schémas peuvent nécessiter davantage de planification et de maintenance en amont.

Courbe d’apprentissage

La courbe d’apprentissage de GraphQL est plus raide que celle de REST. En outre, les développeurs GraphQL sont généralement plus chers et plus difficiles à trouver que les développeurs REST.

Manque de normalisation

L’une des principales critiques formulées à l’encontre de GraphQL est le manque de normalisation de sa mise en œuvre. Les API REST disposent d’un ensemble de principes et de bonnes pratiques bien établis, tandis que la documentation GraphQL ne fournit que des conseils généraux sur la manière de les mettre en œuvre. Cela peut entraîner des incohérences et des confusions dans la conception et l’utilisation des API GraphQL.

Sécurité

L’avantage de GraphQL est que les clients peuvent demander exactement ce dont ils ont besoin, mais d’un autre côté, cela peut constituer un risque potentiel pour la sécurité. Il est important de valider et d’assainir correctement les entrées des utilisateurs afin d’empêcher l’exécution de requêtes malveillantes.

Comment construire une API GraphQL ?

Cette section de l’article examine comment créer une API GraphQL avec Back4app et s’y connecter à partir d’un frontend Next.js.

Conditions préalables

  • Expérience avec JavaScript ES6
  • Expérience avec React et Next.js
  • Compréhension de base de GraphQL

Qu’est-ce que Back4app ?

Back4app est une solution exceptionnelle de Backend as a Service (BaaS) qui fonctionne sur la base d’un logiciel libre. La plateforme offre un large éventail de fonctionnalités qui permettent aux utilisateurs de développer plus facilement et plus rapidement des applications web et mobiles. Elle permet aux entreprises de se concentrer sur leur logique commerciale sans avoir à se préoccuper du backend ou de l’infrastructure sous-jacente.

Back4app est livré avec un tableau de bord facile à utiliser qui est rempli de fonctionnalités, et une interface en ligne de commande (CLI). Il fournit également des kits de développement logiciel (SDK) pour divers outils populaires tels que Node.js, Flutter, React Native, Android, Angular, iOS, et plus encore.

Back4app suit un modèle de tarification simple qui peut répondre aux besoins de n’importe quelle application. Ils proposent également un plan gratuit (sans carte de crédit) qui est idéal pour les tests et le prototypage.

Vous voulez en savoir plus sur Back4app ? Consultez la page Pourquoi utiliser Back4app ?

Introduction du projet

Nous allons construire une simple application web TODO. L’application sera composée de deux parties : le backend et le frontend. Le backend sera alimenté par une API GraphQL et déployé sur Back4app. Le frontend, quant à lui, sera écrit en TypeScript en utilisant le framework Next.js. Pour connecter le frontend au backend, nous utiliserons le client Apollo.

L’application finale se présentera comme suit :

Aperçu du projet back4app-graphql

Backend

Créer l’application Back4app

Pour procéder aux étapes suivantes, vous devez disposer d’un compte Back4app. Si vous en avez déjà un, veuillez vous connecter. Sinon, n’hésitez pas à créer un compte gratuit.

Pour utiliser Back4app, la première étape consiste à créer une application. Une fois connecté à votre tableau de bord, vous pourrez voir la liste de vos applications actuelles. Pour créer une nouvelle application, cliquez sur “Créer une nouvelle application”.

Back4app Création d'applications

Comme nous construisons une API GraphQL, choisissez l’option “Backend as a Service” et spécifiez un nom unique pour votre application. De plus, choisissez “NoSQL” comme type de base de données.

Attendez patiemment que Back4app configure tout ce qui est nécessaire à votre application, y compris la base de données, la couche d’application, la mise à l’échelle, les sauvegardes et la sécurité.

Une fois la configuration terminée, vous serez dirigé vers le tableau de bord de votre application.

Création de l'application Back4app

Définir les modèles de base de données

Comme nous construisons une simple application TODO, nous n’aurons besoin que d’un seul modèle de base de données.

Pour commencer, allez sur votre tableau de bord Back4app et localisez l’option “Base de données” dans la barre latérale. De là, choisissez “Créer une classe”, et donnez-lui le nom de “Tâche”. Assurez-vous de sélectionner “Public Read and Write Enabled” (Lecture et écriture publiques activées), puis cliquez sur “Create class & add columns” (Créer une classe et ajouter des colonnes).

Back4app Définir le modèle

Inclure les colonnes suivantes :

+-----------+------------------+---------------+----------+
| Data type | Name             | Default value | Required |
+-----------+------------------+---------------+----------+
| String    | name             | <leave blank> | yes      |
+-----------+------------------+---------------+----------+
| String    | description      | <leave blank> | no       |
+-----------+------------------+---------------+----------+
| Boolean   | isDone           | false         | no       |
+-----------+------------------+---------------+----------+

Après avoir créé votre modèle de base de données, vous remarquerez que quatre colonnes de base de données ont été ajoutées automatiquement :

  1. objectId est la clé primaire de votre objet
  2. updatedAt est l’horodatage de la dernière mise à jour
  3. createdAt est l’horodatage de la création
  4. ACL définit la “liste de contrôle d’accès”

Gardez-les à l’esprit car nous en aurons besoin plus tard dans le tutoriel lorsque nous travaillerons sur les requêtes et les mutations GraphQL.

Pour vous familiariser avec le tableau de bord de Back4app, essayez d’ajouter deux exemples de tâches, par exemple :

+-----------------+----------------------------------------+--------+
| name            | description                            | isDone |
+-----------------+----------------------------------------+--------+
| GraphQL backend | Create a GraphQL backend via Back4app. | false  |
+-----------------+----------------------------------------+--------+
| Learn GraphQL   | Learn the basics of GraphQL.           | true   |
+-----------------+----------------------------------------+--------+

Console API GraphQL

La console API GraphQL nous permet de tester les requêtes et les mutations GraphQL avant de les mettre en œuvre dans le code. Pour accéder à la console, sélectionnez “API” dans la barre latérale, puis “Console > GraphQL”.

Console GraphQL de Back4app

La console est extrêmement facile à utiliser. Sur le côté gauche, nous pouvons entrer nos requêtes et mutations personnalisées et les résultats sont affichés sur le côté droit.

Pour vérifier si tout fonctionne, exécutez la requête suivante :

query CheckHealth {
    health
}

Vous devriez obtenir la réponse JSON suivante :

{
  "data": {
    "health": true
  }
}

L’un des grands avantages de Back4app est qu’il est basé sur Parse. Lorsque nous avons créé notre modèle de base de données, Parse a automatiquement configuré GraphQL pour nous. Cela inclut la génération d’un schéma GraphQL, de documents, etc.

Essayons de dresser la liste des tâches et de leurs détails à partir de la base de données :

query GetTasks {
  tasks {
    count
    edges {
      node {
        id
        name
        description
        isDone
      }
    }
  }
}

Vous devriez obtenir une réponse similaire :

{
  "data": {
    "tasks": {
      "count": 2,
      "edges": [
        {
          "node": {
            "id": "VGFzazpXQkJzSkRtV2xU",
            "name": "GraphQL backend",
            "description": "Create a GraphQL backend via Back4app.",
            "isDone": false
          }
        },
        {
          "node": {
            "id": "VGFzazpnM2lhNzdwUXBp",
            "name": "Learn GraphQL",
            "description": "Learn the basics of GraphQL.",
            "isDone": true
          }
        }
      ]
    }
  }
}

L’obtention d’un objet spécifique, la création d’objets, leur mise à jour, etc. se font de la même manière. Je n’entrerai pas trop dans les détails maintenant puisque j’expliquerai ces requêtes et mutations plus tard dans le tutoriel. De plus, la documentation de Back4app couvre bien ces sujets :

  1. Création d’un objet
  2. Obtenir un objet
  3. Recherche d’objets
  4. Mise à jour d’un objet
  5. Suppression d’un objet
  6. Authentification

C’est tout pour la partie backend. Dans la prochaine section, nous commencerons à travailler sur le frontend.

Frontend

Créer l’application suivante

La façon la plus simple de démarrer un projet Next.js est d’utiliser l’utilitaire create-next-app. Ouvrez votre terminal et exécutez la commande suivante :

$ yarn create next-app

√ What is your project named? ... back4app-graphql
√ Would you like to use TypeScript with this project? ... No
√ Would you like to use ESLint with this project? ... Yes
√ Would you like to use the `src/` directory with this project? ... No
√ Would you like to use the experimental `app/` directory with this project? ... No
√ What import alias would you like configured? ... @/*

Successfully created a Next.js app.

Ensuite, lancez le serveur de développement :

$ yarn dev

Naviguez vers http://localhost:3000 et vous devriez voir la page d’accueil par défaut de Next.js.

NextJS Default Landing Page

ChakraUI

Pour accélérer et simplifier le processus de construction de l’interface utilisateur et de l’interface utilisateur, nous utiliserons ChakraUI. Chakra UI est une bibliothèque de composants simple, modulaire et accessible qui vous donne tout ce dont vous avez besoin pour construire vos applications React.

En cas de problème, reportez-vous à ChakraUI : Démarrer avec Next.js.

Pour l’installer, exécutez :

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion

Ensuite, naviguez vers votre _pages/app.tsx et enveloppez votre application avec le ChakraProvider comme suit :

// pages/_app.tsx

import "../styles/globals.css";
import type {AppProps} from "next/app";
import {ChakraProvider} from "@chakra-ui/react";

export const theme = extendTheme({});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}

export default MyApp;

N’oubliez pas d’importer le ChakraProvider:

import {ChakraProvider} from "@chakra-ui/provider";

Pour éviter les flashs de couleur aléatoires, assurez-vous de charger le script de mode de couleur avant le contenu. Pour ce faire, vous pouvez utiliser _document.js comme suit :

// pages/_document.tsx

import {ColorModeScript} from "@chakra-ui/react";
import { Html, Head, Main, NextScript } from "next/document";
import {theme} from "@/pages/_app";

export default function Document() {
  return (
    <Html lang='en'>
      <Head />
      <body>
        <ColorModeScript initialColorMode={theme.config.initialColorMode} />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Vous avez installé ChakraUI avec succès.

Interface utilisateur

Passons maintenant à la création de l’interface utilisateur. Notre application web comportera les deux pages suivantes :

  1. / affiche la liste des tâches
  2. créer/ affiche le formulaire de création de tâches

Commencez par remplacer pages/index.tsx par le contenu suivant :

// pages/index.tsx

import type {NextPage} from "next";
import {
    Button, Card, CardBody, Container,
    Heading, HStack, Stack, Text, VStack
} from "@chakra-ui/react";
import Link from "next/link";

let data = {
  "tasks": {
    "count": 2,
    "edges": [
      {
        "node": {
          "id": "VGFzazpXQkJzSkRtV2xU",
          "name": "GraphQL backend",
          "description": "Create a GraphQL backend via Back4app.",
          "isDone": false
        }
      },
      {
        "node": {
          "id": "VGFzazpnM2lhNzdwUXBp",
          "name": "Learn GraphQL",
          "description": "Learn the basics of GraphQL.",
          "isDone": true
        }
      }
    ]
  }
};

const ListPage: NextPage = () => {

  const handleMarkAsDone = async (id: string, isDone: boolean) => {
    console.log("TODO: mark task as done and refetch");
  };

  const handleDelete = async (id: string) => {
    console.log("TODO: delete task and refetch");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/create">
            <Button size="sm" colorScheme="blue">
              Create task
            </Button>
          </Link>
        </HStack>
        <VStack spacing={4}>
          {data.tasks.edges.map((edge) => {
            let task = edge.node;
            return (
              <Card key={task.id} w="100%">
                <CardBody>
                  <Stack direction="column">
                    <Heading as="h2" size="md">
                      {task.isDone ? "✔️" : "❌"}{" "}
                      {task.name}
                    </Heading>
                    <Text>
                      {task.description}
                    </Text>
                    <Stack direction="row" pt={2}>
                      <Button size="sm" colorScheme="blue" onClick={() => handleMarkAsDone(task.id, task.isDone)}>
                        Toggle done
                      </Button>
                      <Button size="sm" colorScheme="red" onClick={() => handleDelete(task.id)}>
                        Delete
                      </Button>
                    </Stack>
                  </Stack>
                </CardBody>
              </Card>
            );
          })}
        </VStack>
      </Container>
    </>
  );
};

export default ListPage;
  1. Nous avons utilisé ChakraUI pour concevoir l’interface utilisateur.
  2. Les tâches sont actuellement chargées à partir du tableau statique nommé data.
  3. Nous utiliserons ultérieurement handleMarkAsDone() et handleDelete() pour envoyer des requêtes API GraphQL.

Ensuite, créez un fichier create.tsx dans le dossier pages avec le contenu suivant :

// pages/create.tsx

import type {NextPage} from "next";
import {
  Button, Card, CardBody, CardHeader, Container, FormControl,
  FormLabel, Heading, HStack, Input, Stack, Switch, Text
} from "@chakra-ui/react";
import Link from "next/link";
import {useState} from "react";
import {useRouter} from "next/router";

const CreatePage: NextPage = () => {
  const router = useRouter();

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [isDone, setIsDone] = useState(false);

  const [formError, setFormError] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    console.log("TODO: call the GraphQL API and redirect");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/">
            <Button size="sm" colorScheme="blue">
              View list
            </Button>
          </Link>
        </HStack>
        <Card>
          <CardHeader>
            <Stack direction="column">
              <Heading as="h2" size="md">Create task</Heading>
              <Text>
                Fill out the form and press &quot;Create&quot; to create a new task.
              </Text>
            </Stack>
          </CardHeader>
          <CardBody>
            <form onSubmit={handleSubmit}>
              <Stack direction="column">
                {formError && <Text color="red.500" fontWeight="bold">{formError}</Text>}
                <FormControl>
                  <FormLabel>Name</FormLabel>
                  <Input type="text" value={name} onChange={(event) => setName(event.target.value)}/>
                </FormControl>
                <FormControl>
                  <FormLabel>Description</FormLabel>
                  <Input type="text" value={description} onChange={(event) => setDescription(event.target.value)}/>
                </FormControl>
                <FormControl display="flex" alignItems="center">
                  <FormLabel mb="0">
                    Is done?
                  </FormLabel>
                  <Switch isChecked={isDone} onChange={() => setIsDone(!isDone)}/>
                </FormControl>
                <Button size="sm" colorScheme="blue" type="submit">Create task</Button>
              </Stack>
            </form>
          </CardBody>
        </Card>
      </Container>
    </>
  );
};

export default CreatePage;
  1. Nous avons à nouveau utilisé les composants ChakraUI pour créer l’interface utilisateur.
  2. Nous avons créé un formulaire contrôlé par React pour créer des tâches.
  3. La fonction handleSubmit() sera utilisée ultérieurement pour envoyer une demande d’API.

Relancez votre serveur web et visitez votre application web à l’adresse http://localhost:3000. Vous devriez voir les deux tâches codées en dur. Cliquez ensuite sur “Créer une tâche” pour afficher le formulaire de création de tâche.

Back4app GraphQL Create Task

Client GraphQL

Pour se connecter à une API GraphQL depuis le frontend, vous devez d’abord installer un client GraphQL. Je vous suggère d’opter pour le client Apollo, car il est facile à configurer, n’est pas influencé et ne nécessite pas beaucoup d’éléments de base.

Commencez par installer @apollo/client et graphql:

$ yarn add @apollo/client graphql

Pour initialiser le client, vous devez fournir vos identifiants API Back4app. La façon la plus simple d’obtenir vos identifiants est de naviguer dans votre GraphQL Console et de prendre note des en-têtes.

Références GraphQL de Back4app

Puisque vous ne voulez pas exposer vos clés d’API dans le code source, créez un fichier .env.local à la racine du projet avec le contenu suivant :

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<YOUR_PARSE_APP_ID>
NEXT_PUBLIC_PARSE_MASTER_KEY=<YOUR_PARSE_MASTER_KEY>
NEXT_PUBLIC_PARSE_CLIENT_KEY=<YOUR_PARSE_CLIENT_KEY>

Ensuite, naviguez vers pages/_app.tsx et initialisez le client Apollo, puis enveloppez votre application avec le ApolloProvider comme suit :

// pages/_app.tsx

// ...
import {ApolloClient, ApolloProvider, InMemoryCache} from "@apollo/client";

const client = new ApolloClient({
  uri: "https://parseapi.back4app.com/graphql",
  headers: {
    "X-Parse-Application-Id": process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID,
    "X-Parse-Master-Key": process.env.NEXT_PUBLIC_PARSE_MASTER_KEY,
    "X-Parse-Client-Key": process.env.NEXT_PUBLIC_PARSE_CLIENT_KEY,
  },
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <ApolloProvider client={client}>
        <Component {...pageProps} />
      </ApolloProvider>
    </ChakraProvider>
  );
}

Attendez que votre frontend soit recompilé, puis visitez votre application web et vérifiez la console pour voir s’il y a des erreurs. L’absence d’erreur signifie que la connexion a réussi.

Requêtes et mutations GraphQL

La dernière chose à faire est de définir vos requêtes et mutations GraphQL, puis de les appeler depuis votre code React.

Pour activer l’assistance au code GraphQL dans votre IDE, naviguez vers la Back4app GraphQL Console, sélectionnez “Schema” sur la barre latérale, et téléchargez-la en tant que SDL. Créez ensuite un nouveau fichier nommé schema.graphql à la racine du projet et collez-y le contenu de la SDL.

Tout d’abord, naviguez vers pages/index.tsx et ajoutez les requêtes suivantes après les importations :

// pages/index.tsx

const GET_TASKS = gql`
  query GetTasks {
    tasks {
      count
      edges {
        node {
          id
          name
          description
          isDone
        }
      }
    }
  }
`;

const UPDATE_TASK = gql`
  mutation UpdateTask($id: ID!, $isDone: Boolean!) {
    updateTask(input: { id: $id, fields: { isDone: $isDone } }) {
      task {
        isDone
        updatedAt
      }
    }
  }
`;

const DELETE_TASK = gql`
  mutation DeleteTask($id: ID!) {
    deleteTask(input: { id: $id }) {
      task {
        id
      }
    }
  }
`;

Ces trois requêtes sont assez explicites. La première renvoie une liste de toutes les tâches, la deuxième met à jour la propriété isDone d’une tâche spécifique et la troisième supprime une tâche spécifique.

Ensuite, modifiez le haut de ListPage comme suit :

// pages_index.tsx

// ...

const ListPage: NextPage = () => {

  const {loading, error, data, refetch} = useQuery(GET_TASKS);
  const [deleteTask] = useMutation(DELETE_TASK);
  const [updateTask] = useMutation(UPDATE_TASK);

const handleMarkAsDone = async (id: string, isDone: boolean) => {
    try {
      const updateTaskResponse = await updateTask({
        variables: {id: id, isDone: !isDone}
      });
      console.debug(updateTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      const deleteTaskResponse = await deleteTask({
        variables: {id: id},
      });
      console.debug(deleteTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  if (error) return <p>Oops, something went wrong.</p>;
  if (loading) return <Spinner/>;

  // ...
};

export default ListPage;
  1. Nous avons utilisé useQuery() pour exécuter la requête GET_TASKS et stocker le résultat.
  2. Nous avons utilisé useMutation() pour définir les mutations GraphQL.
  3. Nous avons mis à jour handleMarkAsDone() et handleDelete() pour utiliser les crochets de mutation.

Modifiez ensuite pages/create.tsx de la même manière :

const CREATE_TASK = gql`
  mutation CreateTask($name: String!, $description: String, $isDone: Boolean!) {
    createTask(
      input: {
        fields: { name: $name, description: $description, isDone: $isDone }
      }
    ) {
      task {
        id
      }
    }
  }
`;

const CreatePage: NextPage = () => {

  // ...

  const [createTask] = useMutation(CREATE_TASK);

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    createTask({
      variables: {name: name, description: description, isDone: isDone}
    }).then(response => {
      router.push("/");
    });
  };

  // ...
};

export default CreatePage;

N’oubliez pas les importations :

import {gql, useMutation, useQuery} from "@apollo/client";

Super, c’est ça !

Relancez votre serveur de développement et visitez votre application web. Vérifiez que les tâches sont chargées depuis la base de données, essayez de créer une nouvelle tâche, de la marquer comme terminée et de la supprimer.

Conclusion

En conclusion, GraphQL est un bon choix pour construire des API complexes en raison de ses capacités d’interrogation flexibles et de sa récupération efficace des données. Bien qu’elle présente de nombreux avantages par rapport à l’API REST traditionnelle, il existe certains inconvénients que vous devez prendre en compte lorsque vous démarrez un projet.

Dans cet article, nous avons discuté des avantages et des inconvénients de GraphQL, nous l’avons comparé aux API REST et nous avons introduit une partie de la terminologie GraphQL. Vous devriez maintenant être en mesure de construire votre propre API GraphQL sur Back4app et de vous y connecter à partir d’un frontend JavaScript.

Vous pouvez récupérer le code source final sur GitHub.

FAQ

Qu’est-ce que GraphQL ?

GraphQL est un langage de requête et un environnement d’exécution côté serveur permettant de développer des API puissantes et flexibles.

Quelles sont les principales différences entre REST et GraphQL ?

REST est une approche standardisée et simple pour construire des services web, tandis que GraphQL offre des capacités de requête plus flexibles et élimine le sous-rapatriement et le sur-rapatriement de données.

Quels sont les termes couramment utilisés dans GraphQL ?

– Schéma : une description des données disponibles via une API GraphQL.
– Résolveur : une fonction qui récupère les données d’un champ spécifique dans une requête GraphQL.
– Requête (Query) : une demande en lecture seule de données depuis une API GraphQL.
– Mutation : une demande de modification de données via une API GraphQL.
– Abonnement (Subscription) : une demande de mise à jour en temps réel via une API GraphQL.

Comment créer une API GraphQL ?

1. Créez un compte gratuit sur Back4app.
2. Concevez les modèles de base de données.
3. Rédigez les requêtes et mutations via la console GraphQL API de Back4app.
4. Installez un client GraphQL (comme Apollo ou Relay) dans votre projet frontend.
5. Initialisez le client et connectez-vous à l’API GraphQL.


Leave a reply

Your email address will not be published.