Einleitung: Warum GraphQL und C++ eine leistungsstarke Kombination sind
GraphQL hat sich zum Standard für moderne APIs entwickelt und bietet Flexibilität und Effizienz im Vergleich zu REST. Aber wie implementiert man es in C++ – einer Sprache, die für ihre Leistung und Strenge bekannt ist? In diesem Tutorial werden wir die Erstellung einer vollwertigen GraphQL-API in C++ mit der Bibliothek cppgraphqlgen durchgehen. Sie lernen, wie Sie ein Schema definieren, Resolver schreiben, Abfragen und Mutationen verarbeiten. Die Codebeispiele sind praxisnah, damit Sie sie sofort in Ihren Projekten anwenden können.
Am Ende des Artikels werden Sie in der Lage sein, einen einfachen, aber funktionsfähigen GraphQL-Server in C++ zu erstellen, der Anfragen annimmt und Daten zurückgibt. Los geht's!
Installation und Einrichtung der Umgebung
Für die Arbeit benötigen wir:
- Einen Compiler mit C++17-Unterstützung (z.B. GCC 8+ oder Clang 7+)
- CMake (Version 3.14+)
- Die Bibliothek
cppgraphqlgen(Codegenerierung aus dem GraphQL-Schema) - Einen HTTP-Server (z.B.
cpp-httplibder Einfachheit halber)
Wir installieren die Abhängigkeiten über vcpkg oder bauen sie manuell. Für dieses Tutorial verwenden wir vcpkg:
git clone https://github.com/Microsoft/vcpkg.gitcd vcpkg./bootstrap-vcpkg.sh./vcpkg install cppgraphqlgen cpp-httplibErstellen wir die Projektstruktur:
graphql-cpp-tutorial/├── schema.graphql├── CMakeLists.txt├── src/│ ├── main.cpp│ ├── resolver.cpp│ └── resolver.hSchritt 1: Definieren des GraphQL-Schemas
Erstellen wir eine Datei schema.graphql mit einem einfachen Schema zur Verwaltung von Aufgaben (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!}Dieses Schema beschreibt:
- Query – Abrufen einer Liste von Aufgaben oder einer einzelnen Aufgabe nach ID
- Mutation – Hinzufügen einer neuen Aufgabe und Markieren als erledigt
- Type Todo – Ein Objekt mit den Feldern id, title, completed
Das Schema ist der Vertrag unserer API. Als Nächstes generieren wir daraus C++-Code.
Schritt 2: Generieren von C++-Code aus dem Schema
Wir verwenden das Dienstprogramm graphqlgenerategen aus dem Paket cppgraphqlgen:
graphqlgenerategen schema.graphql --output-dir ./generatedNach der Ausführung erscheinen im Ordner generated die Dateien:
TodoObject.h– Klasse für den Typ TodoQueryObject.h– Basisklasse für Query-ResolverMutationObject.h– Basisklasse für Mutation-Resolverschema.h– Integration des Schemas
Diese Dateien enthalten generierte Schnittstellen, die wir implementieren müssen.
Schritt 3: Implementierung der Resolver
Erstellen wir eine Datei resolver.h mit den Deklarationen:
#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;};
Jetzt implementieren wir die Logik in resolver.cpp:
#include "