Introduction : Pourquoi GraphQL et C++ sont une combinaison puissante
GraphQL est devenu un standard pour les API modernes, offrant flexibilité et efficacité par rapport à REST. Mais comment l'implémenter en C++ — un langage connu pour ses performances et sa rigueur ? Dans ce tutoriel, nous allons détailler la création d'une API GraphQL complète en C++ en utilisant la bibliothèque cppgraphqlgen. Vous apprendrez à définir un schéma, écrire des résolveurs, traiter des requêtes et des mutations. Les exemples de code seront pratiques pour que vous puissiez les appliquer immédiatement dans vos projets.
À la fin de cet article, vous serez capable de créer un serveur GraphQL simple mais fonctionnel en C++, qui accepte les requêtes et retourne des données. C'est parti !
Installation et configuration de l'environnement
Pour travailler, nous aurons besoin de :
- Un compilateur supportant C++17 (par exemple, GCC 8+ ou Clang 7+)
- CMake (version 3.14+)
- La bibliothèque
cppgraphqlgen(génération de code à partir du schéma GraphQL) - Un serveur HTTP (par exemple,
cpp-httplibpour simplifier)
Installons les dépendances via vcpkg ou compilons manuellement. Pour ce tutoriel, nous utilisons vcpkg :
git clone https://github.com/Microsoft/vcpkg.gitcd vcpkg./bootstrap-vcpkg.sh./vcpkg install cppgraphqlgen cpp-httplibCréons la structure du projet :
graphql-cpp-tutorial/├── schema.graphql├── CMakeLists.txt├── src/│ ├── main.cpp│ ├── resolver.cpp│ └── resolver.hÉtape 1 : Définir le schéma GraphQL
Créons un fichier schema.graphql avec un schéma simple pour la gestion des tâches (Todo) :
type Query { todos: [Todo!]! todo(id: ID!): Todo}
type Mutation { addTodo(title: String!): Todo! completeTodo(id: ID!): Todo}
type Todo { id: ID! title: String! completed: Boolean!}Ce schéma décrit :
- Query — obtenir la liste des tâches ou une tâche par son ID
- Mutation — ajouter une nouvelle tâche et marquer une tâche comme terminée
- Type Todo — un objet avec les champs id, title, completed
Le schéma est le contrat de notre API. Ensuite, nous générerons le code C++ à partir de celui-ci.
Étape 2 : Génération du code C++ à partir du schéma
Utilisons l'utilitaire graphqlgenerategen du paquet cppgraphqlgen :
graphqlgenerategen schema.graphql --output-dir ./generatedAprès exécution, les fichiers suivants apparaîtront dans le dossier generated :
TodoObject.h— classe pour le type TodoQueryObject.h— classe de base pour les résolveurs QueryMutationObject.h— classe de base pour les résolveurs Mutationschema.h— intégration du schéma
Ces fichiers contiennent les interfaces générées que nous devons implémenter.
Étape 3 : Implémentation des résolveurs
Créons un fichier resolver.h avec les déclarations :
#include "generated/QueryObject.h"#include "generated/MutationObject.h"#include <vector>#include <memory>
struct Todo { std::string id; std::string title; bool completed;};
class QueryResolver : public graphql::todo::QueryObject {public: std::vector<std::shared_ptr<graphql::todo::TodoObject>> getTodos() const override; std::shared_ptr<graphql::todo::TodoObject> getTodo(const std::string& id) const override;
private: static std::vector<Todo> todos_;};
class MutationResolver : public graphql::todo::MutationObject {public: std::shared_ptr<graphql::todo::TodoObject> applyAddTodo(const std::string& title) override; std::shared_ptr<graphql::todo::TodoObject> applyCompleteTodo(const std::string& id) override;};Implémentons maintenant la logique dans resolver.cpp :
#include "