Les API REST peuvent vous limiter, en vous obligeant à faire des pieds et des mains pour obtenir les données que vous souhaitez. GraphQL renverse cette tendance. Vous demandez ce dont vous avez besoin, et c'est tout ce que vous obtenez, sans payloads inutiles ni remplissage.
Si vous avez déjà essayé de connecter une application avec beaucoup de données, vous avez probablement ressenti les limites de REST. Parfois, vous finissez par fouiller dans une pile de données que vous n'avez pas demandées. D'autres fois, la seule chose dont vous avez besoin n'est tout simplement pas là. Dans tous les cas, vos utilisateurs ressentent le décalage.
Imaginez votre application de vitrine. Tout ce que vous voulez, ce sont les noms des clients et leurs dernières commandes. Si vous utilisez REST, vous finirez par faire une série de requêtes distinctes juste pour rassembler les informations. Avec GraphQL, vous lancez une seule requête vers un seul point de terminaison et obtenez tout ce dont vous avez besoin en une seule fois.
Exemple REST :
Les appels REST pourraient ressembler à ceci :
GET /client/1
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"age": 30
}
GET /commandes?customerId=1
[
{ "id": 1, "title": "Ordinateur portable" },
{ "id": 2, "title": "Souris" }
]
Cette approche REST envoie des données excessives, ce qui nécessite un travail supplémentaire pour les filtrer.
Exemple GraphQL :
GraphQL gère cela plus efficacement avec une seule requête ciblée :
query {
customer(id: 1) {
name
orders {
title
}
}
}
Résultat :
{
"customer": {
"name": "Alice",
"orders": [
{ "title": "Ordinateur portable" },
{ "title": "Souris" }
]
}
}
La requête unique fournit exactement ce dont le frontend a besoin. Pas d'allers-retours supplémentaires, pas de données redondantes, simplement direct et efficace.
Facebook a créé GraphQL en 2015 afin d'obtenir rapidement des données pour le fil d'actualité. Après l'avoir rendu open source, d'autres entreprises ont commencé à l'utiliser, car il leur permettait de traiter les demandes de données avec plus de précision via un seul point de terminaison.
Voici ce qui distingue GraphQL :
Si vous travaillez avec des structures de données connectées, le système de requête de GraphQL simplifie le développement.
GraphQL n'est pas simplement une API parmi d'autres, c'est un langage de requête qui vous permet d'obtenir exactement les données dont vous avez besoin via un seul point de terminaison. Bien que cela simplifie la communication client-serveur, vous devez comprendre ce que cela apporte.
Contrairement aux API REST, qui nécessitent plusieurs appels pour différentes données, GraphQL regroupe tout en une seule requête. N'oubliez pas que vous devrez tenir compte de la mise en cache et des performances lors de la création.
Voyons comment GraphQL façonne les applications réelles et pourquoi les développeurs le choisissent pour le développement d'API modernes.
GraphQL traite les données de manière unique, ce qui est important pour les développeurs.
GraphQL vous offre une couche API flexible et précise. Grâce à une mise en œuvre réfléchie de la mise en cache, des performances et de la conception du schéma, il peut rendre votre processus de développement plus efficace.
Voyons maintenant comment GraphQL utilise les schémas et les types pour équilibrer flexibilité et performances.
Un schéma GraphQL définit les données avec lesquelles votre API peut fonctionner. Considérez-le comme un contrat entre votre client et votre serveur. À l'aide d'un langage simple appelé SDL (Schema Definition Language), il établit des limites claires pour l'échange de données.
Voyons cela en action avec un type « User » basique :
type User {
id: ID!
name: String!
email: String!
}
type Query {
getUser(id: ID!): User
}
Le schéma agit comme un ensemble de règles claires pour les requêtes de données. Vous indiquez à GraphQL les champs que vous souhaitez, et le schéma vérifie si ces champs existent. C'est comme un menu dans lequel vous pouvez choisir exactement ce dont vous avez besoin.
Les schémas permettent d'organiser les connexions de données de manière à rendre vos requêtes plus efficaces, en vous fournissant uniquement les informations spécifiques que vous recherchez.
Votre schéma montre également comment les différentes parties de vos données sont reliées entre elles. GraphQL vous permet d'interroger ces connexions via un seul point de terminaison, ce qui est plus simple que d'utiliser plusieurs points de terminaison REST.
type Post {
id: ID!
title: String!
content: String!
author: User
}
Chaque publication peut être liée à son auteur. Contrairement aux API REST qui nécessitent plusieurs appels API, les requêtes GraphQL peuvent récupérer à la fois les données de la publication et celles de l'auteur via un seul point de terminaison. Il s'agit d'un langage de requête simplifié pour les API.
Votre schéma doit être à la fois flexible et facile à maintenir si vous souhaitez qu'il évolue avec votre application. Voici ce qui fonctionne :
enum Role {
ADMIN
USER
}
input UpdateUserInput {
id: ID!
name: String
email: String
}
Un schéma bien structuré facilite la communication claire entre les clients et les serveurs via un seul point de terminaison.
Voyons comment ces concepts de schéma fonctionnent dans la pratique avec GraphQL.
GraphQL vous offre deux outils simples pour gérer les données : les requêtes et les mutations. Ceux-ci facilitent l'utilisation de votre API.
query {
getUser(id: "1") {
id
name
email
}
}
mutation {
updateUser(input: { id: "1", name: "John Doe" }) {
name
email
}
}
GraphQL simplifie les choses en proposant deux méthodes principales pour travailler avec les données : les requêtes pour obtenir des informations et les mutations pour les modifier. Tout se passe via un seul point de connexion, ce qui rend votre code clair et facile à suivre.
GraphQL fonctionne avec des mises à jour en temps réel grâce à des abonnements qui nécessitent des connexions WebSocket et une configuration du serveur. Une fois qu'il est en cours d'exécution, votre application reçoit les mises à jour dès qu'elles se produisent.
Voici à quoi ressemblent les abonnements dans une application de chat :
subscription {
onNewMessage(roomId: "123") {
content
timestamp
}
}
Lorsqu'un nouvel événement se produit (comme un nouveau message de chat), les abonnements envoient les mises à jour aux clients connectés via des connexions WebSocket. Vous n'aurez pas besoin de vérifier régulièrement les mises à jour, mais vous devrez configurer votre serveur de manière spécifique et disposer d'une prise en charge WebSocket.
GraphQL et REST prennent des chemins différents en matière d'erreurs. Dans REST, vous obtenez un code d'état HTTP et un message d'erreur dans le corps de la réponse, ce qui vous permet de savoir ce qui a échoué. GraphQL reste simple. À moins d'un problème réseau, vous obtiendrez toujours un 200 OK, et toutes les erreurs s'affichent dans un champ dédié aux erreurs dans la réponse.
Jetez un œil :
{
"errors": [
{
"message": "User not found",
"path": ["getUser"]
}
]
}
GraphQL fournit des messages d'erreur clairs lorsque quelque chose ne fonctionne pas. La validation du schéma aide les développeurs à détecter et à corriger les problèmes pendant le développement plutôt qu'en production.
À l'instar d'un traducteur efficace, GraphQL simplifie la communication entre votre application et vos données. Il regroupe tout ce dont vous avez besoin dans une seule requête et assure la fluidité du flux d'informations.
Voyons comment faire fonctionner GraphQL en production avec Apollo Server, un outil fiable pour créer des API GraphQL auquel de nombreux développeurs font confiance.
Vous pouvez créer une API GraphQL qui gère toutes vos données via un seul point de terminaison avec le serveur Apollo. La mise en route est très simple.
npm install apollo-server graphql
Créez un serveur de base:
Voici un exemple de création d'un serveur Apollo avec un schéma et un résolveur types.
const { ApolloServer, gql } = require('apollo-server');
// Définir le schéma GraphQL à l'aide de `gql`
const typeDefs = gql`
type Query {
hello: String
}
`;
// Définir les résolveurs pour le schéma
const resolvers = {
Query: {
hello: () => 'Hello, world!',
},
};
// Créer une nouvelle instance Apollo Server
const server = new ApolloServer({ typeDefs, resolvers });
// Démarrer le serveur et enregistrer l'URL
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
Pour sécuriser votre API GraphQL, ajoutez une étape de validation JWT à votre couche middleware. Voici comment procéder :
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => {
const token = req.headers.authorization || '';
const user = validateJWT(token); // Fonction personnalisée pour décoder/valider JWT
return { user };
},
});
Cette configuration de sécurité signifie que seuls les utilisateurs connectés peuvent utiliser votre API GraphQL. Vous devrez également configurer des autorisations au niveau des champs et des types. Cela permettra aux utilisateurs d'accéder et de modifier uniquement les données qu'ils sont censés voir, tout en conservant l'efficacité de votre point de terminaison unique.
Voyons maintenant comment connecter GraphQL à des applications clientes modernes à l'aide d'Apollo Client, un outil qui simplifie la gestion des données frontales.
Configurons Apollo Client, un client GraphQL qui simplifie vos connexions API. Vous pouvez l'utiliser pour relier votre front-end à une API GraphQL via un point de terminaison unique, afin de n'obtenir que les données dont vous avez besoin.
npm install @apollo/client graphql
Initialisez Apollo Client:
Configuration d'Apollo Client avec un point de terminaison GraphQL et une mise en cache en mémoire :
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://example.com/graphql',
cache: new InMemoryCache(),
});
En encapsulant votre application React avec ApolloProvider, vous facilitez les requêtes de données dans l'ensemble de votre application :
import { ApolloProvider } from '@apollo/client';
import App from './App';
const Root = () => (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
Une fois Apollo Client prêt, sécurisons notre API et assurons-nous que les utilisateurs ne peuvent accéder qu'aux données qu'ils sont censés voir.
Voici comment fonctionne le contrôle d'accès basé sur les rôles avec les jetons JWT dans les résolveurs. Voici un exemple pratique montrant comment les appels API sont autorisés :
const resolvers = {
Query: {
getUser: async (_, { id }, { user }) => {
if (!user || user.role !== 'ADMIN') {
throw new Error('Unauthorized');
}
return await User.findById(id);
},
},
};
Apollo Server récupère vos données API à partir du jeton JWT et les rend disponibles dans vos résolveurs GraphQL. Vous pouvez ainsi utiliser ces données pour vérifier si quelqu'un est autorisé à interroger ou à modifier la source de données.
Les tests permettent de s'assurer que votre API fonctionne correctement. Nous utiliserons Jest pour nos tests, car cet outil est simple et efficace.
Écrivez un test pour une requête:
describe('GraphQL Queries', () => {
it('fetches user data', async () => {
const query = `
query {
getUser(id: "1") {
id
name
}
}
`;
const response = await executeGraphQL(query); // Remplacer par la logique de configuration du test
expect(response.data.getUser.name).toBe('John Doe');
});
});
Détectez les problèmes rapidement en effectuant des tests fréquents. Votre schéma restera fiable et vous éviterez les problèmes de débogage. Maintenant que nous avons abordé les tests, voyons comment optimiser les performances de votre API GraphQL.
Les API GraphQL sont souvent confrontées au problème de requête n+1. Cela se produit lorsqu'une requête API obtient une donnée, puis a besoin de données connexes, ce qui génère plusieurs appels à la base de données qui ralentissent le processus.
DataLoader accélère GraphQL en combinant les appels à la base de données et en stockant les résultats. Voici comment GraphQL optimise les appels API pour obtenir exactement les données dont vous avez besoin :
const userLoader = new DataLoader(keys =>
User.findMany({ where: { id: keys } })
);
// Exemple de résolveur
const resolvers = {
Post: {
author: (post) => userLoader.load(post.authorId),
},
};
DataLoader combine les requêtes de base de données, réduisant ainsi la charge du serveur et accélérant les réponses API. Il facilite la gestion des API.
Voyons maintenant comment la mise en cache peut rendre votre API GraphQL encore plus rapide.
GraphQL n'intègre pas de mise en cache, mais les outils de son écosystème vous offrent des options de mise en cache fiables. Voici ce que vous pouvez faire pour ajouter la mise en cache à vos applications GraphQL :
Voyons comment configurer la mise en cache avec Apollo Client :
import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries';
import { ApolloClient, InMemoryCache } from '@apollo/client';
// Configurer Apollo Client avec des requêtes persistantes
const client = new ApolloClient({
link: createPersistedQueryLink().concat(httpLink),
cache: new InMemoryCache(),
});
Surveillez votre API GraphQL pour vous assurer qu'elle reste rapide et fiable. Les outils Apollo vous indiquent quelles requêtes sont populaires et où se produisent les ralentissements.
Lorsque les requêtes ralentissent, vous saurez immédiatement où ajouter de la mise en cache ou utiliser DataLoader pour accélérer les choses. Une surveillance régulière permet de détecter et de résoudre les problèmes rapidement.
Vous trouverez le déploiement avec Upsun simple et rapide. Nous disposons d'outils de mise en cache et de déploiement intégrés qui vous permettent d'exécuter immédiatement votre API en production. Les environnements de test et de production sont rapides à mettre en place, vous pouvez donc commencer à travailler immédiatement.
Si vous disposez d'API qui doivent fonctionner dans différentes régions, notre mise en cache globale garantit une vitesse et une stabilité optimales. Vos utilisateurs n'ont donc pas à attendre : ils obtiennent des réponses rapides où qu'ils se trouvent, et votre service GraphQL reste performant à mesure que vous vous développez.
GraphQL permet aux applications mobiles d'obtenir des données à l'aide d'un seul appel API. Vous demanderez exactement ce dont votre application a besoin, à savoir uniquement les noms d'utilisateur plutôt que les profils complets.
Prenons l'exemple d'une application mobile affichant des profils, des activités et des notifications. Alors que les API REST peuvent nécessiter plusieurs appels, GraphQL peut les regrouper en une seule requête, ce qui peut améliorer l'autonomie de la batterie et les temps de réponse en fonction de votre implémentation spécifique et de votre stratégie de mise en cache.
GraphQL excelle dans le traitement des données liées, vous permettant d'obtenir toutes les informations connexes en une seule requête.
Imaginez que vous consultiez l'historique des commandes d'un client et que vous souhaitiez obtenir des détails sur ce qu'il a acheté, qui le lui a vendu et où se trouve chaque colis à l'heure actuelle. Avec GraphQL, il vous suffit de demander toutes ces informations en une seule fois. Si vous travaillez avec REST, vous devrez passer d'un point de terminaison à l'autre et rassembler vous-même les informations.
Si vous utilisez des microservices, GraphQL peut servir de passerelle API centrale. Des outils tels que Schema Stitching ou Apollo Federation vous permettent de regrouper tous vos services sous un même toit.
Imaginez ceci : les utilisateurs, les commandes et les produits sont répartis entre leurs microservices. GraphQL les relie à l'aide d'un schéma unique. La passerelle détermine où trouver chaque service, traite les demandes et fusionne les données pour vous.
Une fois que vous avez vu cette approche en action, il est plus facile de comparer la manière dont GraphQL et REST gèrent chacun les systèmes distribués.
Les API REST vous fournissent des points de terminaison fixes pour chaque ressource, mais cela ne convient pas toujours. Sans une bonne planification, vous obtiendrez soit plus de données que nécessaire (par exemple, des profils d'utilisateurs complets alors que vous ne souhaitez obtenir que des noms), soit vous devrez effectuer plusieurs appels pour obtenir les données associées. Les API REST modernes gèrent mieux cette situation en vous permettant de sélectionner des champs spécifiques et en utilisant d'autres méthodes pour garantir l'efficacité.
GraphQL vous permet d'être précis. Un point de terminaison, des données exactes. Vous voulez le nom d'un utilisateur et ses publications récentes ? C'est ce que vous obtenez.
Exemple de réponse REST (surcharge) :
{
"id": "1",
"name": "John Doe",
"birthdate": "1990-01-01",
"address": { "street": "123 Main St", "city": "Example City" }
}
Exemple de requête GraphQL (extraction de données spécifiques) :
query {
getUser(id: "1") {
name
posts {
title
}
}
}
Voyons maintenant comment REST et GraphQL traitent les données dans des situations réelles.
REST fonctionne bien pour les données simples qui correspondent à des points de terminaison. Mais lorsque vous avez besoin de données imbriquées (comme les utilisateurs et leurs publications), vous devez effectuer plusieurs appels ou récupérer des données supplémentaires dont vous n'avez pas besoin.
GraphQL excelle avec les données liées lorsque vous le configurez correctement. Vous écrirez une seule requête pour obtenir exactement ce dont vous avez besoin, ce qui peut accélérer le fonctionnement de votre application lorsqu'elle est correctement configurée. Mais n'oubliez pas que sa vitesse d'exécution dépend de votre configuration de mise en cache et de la façon dont vous la construisez. N'oubliez pas de configurer DataLoader sur votre serveur pour éviter les ralentissements liés aux requêtes N+1.
REST et GraphQL ne gèrent pas les mises à jour de la même manière. Dans REST, il est courant de versionner votre API directement dans l'URL, par exemple /v1/users. Le REST moderne peut également utiliser la négociation de contenu et l'hypermédia pour effectuer des mises à jour sans numéros de version.
GraphQL vous permet de mettre à jour progressivement en marquant les champs comme obsolètes. Votre code continue de fonctionner tout en laissant aux développeurs le temps d'adapter leur code.
Voici comment marquer des champs comme obsolètes dans votre schéma :
type User {
id: ID!
name: String!
email: String @deprecated(reason: "Use 'contactEmail' instead.")
contactEmail: String
}
GraphQL vous permet de mettre à jour votre API progressivement. Vous n'avez pas besoin de pousser tout le monde à effectuer la mise à jour en même temps : les développeurs peuvent modifier leur code quand cela leur convient.
GraphQL est livré avec des outils intégrés qui vous permettent d'explorer facilement les API pendant le développement. Même si vous souhaiterez désactiver des outils tels que GraphiQL et GraphQL Playground en production pour des raisons de sécurité, le système de types vous permet de détecter les erreurs à un stade précoce. Cette vérification des types fonctionne avec la validation des schémas pour repérer rapidement les problèmes et faciliter la collaboration entre les équipes front-end et back-end.
Les API REST fournissent souvent trop de données (surcharge) ou nécessitent plusieurs appels de points de terminaison (sous-charge). Aucune de ces deux situations n'est idéale.
GraphQL vous permet de demander précisément ce dont vous avez besoin en une seule requête. Vous souhaitez récupérer le nom d'un utilisateur et ses dernières publications ? Une seule requête suffit, au lieu de plusieurs points de terminaison REST. Lorsqu'il est correctement implémenté, vous pouvez obtenir des charges utiles plus petites et réduire le trafic réseau. Les workflows de développement peuvent être simplifiés pour certains types d'applications, en particulier celles qui présentent des relations de données complexes.
Voyons comment la mise en cache peut accélérer encore davantage ces requêtes rapides.
Voici ce que vous devez savoir pour accélérer vos applications GraphQL grâce à la mise en cache.
La mise en cache n'est pas une solution universelle. Les API REST fonctionnent bien avec la mise en cache HTTP et les CDN dès leur installation, mais avec GraphQL, vous devrez faire un peu plus d'efforts pour obtenir les mêmes résultats. Il vaut mieux prendre du recul et réfléchir à ce dont votre application a vraiment besoin avant de choisir une approche de mise en cache.
Intégrons la sécurité dans votre API GraphQL dès le départ. Avec une protection adéquate, vous n'aurez pas de problèmes liés à des requêtes imbriquées complexes qui ralentissent votre serveur. Voici ce dont vous avez besoin :
Vous devrez utiliser graphql-shield sur votre serveur pour les règles d'autorisation. Grâce à ce middleware, vous définissez les règles déterminant qui peut voir ou modifier certaines données dans votre schéma GraphQL. Ainsi, les utilisateurs n'ont accès qu'à ce qu'ils sont censés voir.
GraphQL vous offre un langage de requête flexible pour les API. Si GraphQL et REST permettent tous deux d'obtenir des données de manière efficace, la conception axée sur le schéma et le système de types intégré de GraphQL fonctionnent très bien pour certaines tâches. Il dispose d'outils solides pour la vérification des types et les mises à jour en temps réel, ce qui le rend idéal pour les applications modernes qui nécessitent beaucoup de données.
Vous découvrez GraphQL ? Commencez par l'utiliser pour une seule fonctionnalité de votre application. Cela vous permettra d'apprendre les bases tout en conservant vos systèmes actuels.
Essayez d'abord GraphQL avec de petites implémentations. Cela vous permettra de voir s'il correspond aux besoins de votre équipe.
Vous souhaitez commencer à développer avec GraphQL ? Voyons comment vous pouvez vous lancer.
Lorsque vous êtes prêt pour la production, utilisez des outils d'infrastructure tels que Upsun qui offrent des mécanismes de clonage d'environnement et de mise en cache pour assurer le bon déroulement de votre déploiement.
Commencez modestement, choisissez une fonctionnalité à essayer avec GraphQL, testez-la minutieusement, puis développez à partir de là. C'est la voie la plus simple pour créer des API propres et efficaces.