API GraphQL avec C++ : Tutoriel étape par étape
GraphQL est un langage de requête puissant pour les API qui permet aux clients de demander exactement les données dont ils ont besoin, et rien de plus. Bien que le C++ ne soit pas le langage le plus populaire pour construire des API web, ses performances et son contrôle de la mémoire en font un excellent choix pour les systèmes à forte charge. Dans ce tutoriel, nous allons créer un serveur GraphQL fonctionnel en C++ en utilisant la bibliothèque graphql-cpp.
Ce dont vous avez besoin pour commencer
Pour ce projet, vous aurez besoin de :
- Un compilateur avec le support C++17 (GCC 8+, Clang 7+, MSVC 2019+)
- CMake version 3.14 ou supérieure
- La bibliothèque
graphql-cpp(installez via vcpkg ou compilez à partir des sources) - La bibliothèque
libmicrohttpdpour le serveur HTTP
Installez les dépendances via vcpkg :
git clone https://github.com/microsoft/vcpkg.gitcd vcpkg./bootstrap-vcpkg.sh./vcpkg install graphql-cpp libmicrohttpdCréation de la structure de base du projet
Commençons par configurer le projet CMake. Créez un fichier CMakeLists.txt :
cmake_minimum_required(VERSION 3.14)project(graphql-cpp-tutorial)
set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(graphql-cpp CONFIG REQUIRED)find_package(MHD CONFIG REQUIRED)
add_executable(graphql-server main.cpp)target_link_libraries(graphql-server graphql-cpp::graphql-cpp MHD::MHD)Créez maintenant le fichier principal main.cpp avec un serveur minimal :
#include <graphql-cpp/GraphQL.h>#include <microhttpd.h>#include <iostream>#include <string>
using namespace graphql::cpp;
// HTTP request handler functionstatic enum MHD_Result request_handler(void* cls, struct MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls) { const char* response_str = "{\\"data\\":{\\"hello\\":\\"world\\"}}"; struct MHD_Response* response = MHD_create_response_from_buffer( strlen(response_str), (void*)response_str, MHD_RESPMEM_PERSISTENT ); MHD_add_response_header(response, "Content-Type", "application/json"); int ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); return ret == MHD_YES ? MHD_YES : MHD_NO;}
int main() { struct MHD_Daemon* daemon = MHD_start_daemon( MHD_USE_INTERNAL_POLLING_THREAD, 4000, NULL, NULL, &request_handler, NULL, MHD_OPTION_END ); if (daemon == NULL) { std::cerr << "Failed to start server" << std::endl; return 1; } std::cout << "Server running on http://localhost:4000/graphql" << std::endl; getchar(); MHD_stop_daemon(daemon); return 0;}Définition du schéma GraphQL
Ajoutons maintenant un vrai schéma GraphQL. Nous allons créer un type Book et un type racine Query :
#include <graphql-cpp/Schema.h>#include <graphql-cpp/Type.h>#include <vector>#include <memory>
using namespace graphql::cpp;
// Data modelstruct Book { int id; std::string title; std::string author; int year;};
// Book repository (simulating a database)class BookRepository {public: static std::vector<Book> getAll() { return { {1, "War and Peace", "Leo Tolstoy", 1869}, {2, "Crime and Punishment", "Fyodor Dostoevsky", 1866}, {3, "The Master and Margarita", "Mikhail Bulgakov", 1967} }; } static Book getById(int id) { auto books = getAll(); for (const auto& book