GraphQL API mit C++: Schritt-für-Schritt-Tutorial
GraphQL ist eine Abfragesprache für APIs, die von Facebook entwickelt wurde. Im Gegensatz zu REST ermöglicht sie dem Client, nur die Daten anzufordern, die er benötigt, was die übertragene Datenmenge reduziert und die Anwendungsleistung verbessert. In diesem Tutorial erstellen wir einen einfachen GraphQL-Server in C++ unter Verwendung der Bibliothek graphql-cpp. Sie lernen, wie Sie ein Schema definieren, Resolver schreiben und Abfragen und Mutationen verarbeiten.
Was ist GraphQL und warum C++?
GraphQL bietet einen einzigen Endpunkt für alle Abfragen. Die grundlegenden Konzepte sind:
- Schema — Beschreibung der verfügbaren Datentypen und Operationen (Abfragen, Mutationen, Abonnements).
- Abfragen (Queries) — Leseoperationen für Daten.
- Mutationen (Mutations) — Schreib-/Änderungsoperationen für Daten.
- Resolver (Resolvers) — Funktionen, die Daten für jedes Feld zurückgeben.
C++ ist eine leistungsstarke Sprache für hochlastige Systeme. Die Verwendung von GraphQL mit C++ ermöglicht die Erstellung effizienter und skalierbarer APIs. Die Bibliothek graphql-cpp bietet eine praktische Schnittstelle für die Integration.
Installation und Projekteinrichtung
Für die Arbeit benötigen wir:
- Einen C++17-Compiler (z.B. g++ oder MSVC).
- Die Bibliothek
graphql-cpp(Installation über vcpkg oder Build aus dem Quellcode). - Einen HTTP-Server (wir verwenden der Einfachheit halber
cpp-httplib).
Installation über vcpkg
vcpkg install graphql-cppvcpkg install cpp-httplibProjektstruktur
Erstellen Sie die Dateien:
main.cpp— Einstiegspunkt und HTTP-Server.schema.hpp— Definition des GraphQL-Schemas.resolvers.hpp— Implementierung der Resolver.CMakeLists.txt— Build-Konfiguration.
Definition des GraphQL-Schemas
Wir erstellen ein einfaches Schema zur Verwaltung einer Benutzerliste. Der Typ User enthält die Felder id, name und email. Abfragen: users (Liste aller Benutzer) und user(id: ID!) (ein Benutzer). Mutation: addUser(name: String!, email: String!): User.
In der Datei schema.hpp:
#ifndef SCHEMA_HPP#define SCHEMA_HPP
#include <graphqlcpp/GraphQLSchema.h>
using namespace graphqlcpp;
// Definieren des User-Typsauto userType = std::make_shared<ObjectType>( "User", { {"id", Type::NonNull(Type::ID)}, {"name", Type::NonNull(Type::String)}, {"email", Type::NonNull(Type::String)} });
// Definieren des Query-Typsauto queryType = std::make_shared<ObjectType>( "Query", { {"users", Type::List(Type::NonNull(userType))}, {"user", Type::NonNull(userType), {{"id", Type::NonNull(Type::ID)}}} });
// Definieren des Mutation-Typsauto mutationType = std::make_shared<ObjectType>( "Mutation", { {"addUser", Type::NonNull(userType), { {"name", Type::NonNull(Type::String)}, {"email", Type::NonNull(Type::String)} }} });
// Zusammenstellen des Schemasauto schema = std::make_shared<Schema>(queryType, mutationType);
#endif // SCHEMA_HPPImplementierung der Resolver
Resolver sind Funktionen, die Daten für jedes Feld zurückgeben. In unserem Beispiel werden die Daten in einem globalen Vektor gespeichert. In der Datei resolvers.hpp:
#ifndef RESOLVERS_HPP#define RESOLVERS_HPP
#include <vector>#include <string>#include <graphqlcpp/Resolvers.h>
using namespace graphqlcpp;
struct User { std::string id; std::string name; std::string email;};
std::vector<User> users = { {"1",