مقدمة: GraphQL وC++ — ثنائي قوي لـ API حديث
\n\nأصبح GraphQL المعيار الفعلي لبناء واجهات برمجة تطبيقات (API) مرنة وفعالة. بينما تركز معظم الدروس التعليمية على JavaScript أو Python، تظل لغة C++ لا غنى عنها للأنظمة عالية التحميل، وخوادم الألعاب، والحلول المضمنة. في هذا الدليل التعليمي خطوة بخطوة، سنقوم بإنشاء GraphQL API كامل بلغة C++ من الصفر، باستخدام مكتبة graphql-cpp وخادم cpp-httplib.
ستتعلم كيفية إعداد البيئة، تعريف المخطط (schema)، تنفيذ المحللات (resolvers)، وتشغيل الخادم. جميع أمثلة الكود قابلة للتطبيق الفوري في المشاريع الحقيقية.
\n\n1. إعداد البيئة وتثبيت التبعيات
\n\nلبدء العمل، سنحتاج إلى:
\n- \n
- مترجم يدعم C++17 (GCC 8+، Clang 7+، MSVC 2019+) \n
- CMake (الإصدار 3.14+) \n
- مكتبة
graphql-cpp(تنفيذ GraphQL) \n - مكتبة
cpp-httplib(خادم HTTP) \n - مدير الحزم vcpkg (اختياري ولكنه مريح) \n
التثبيت عبر vcpkg
\ngit clone https://github.com/Microsoft/vcpkg.git\ncd vcpkg\n./bootstrap-vcpkg.sh\n./vcpkg install graphql-cpp cpp-httplib nlohmann-json\n\nهيكل المشروع
\ngraphql-cpp-api/\n├── CMakeLists.txt\n├── src/\n│ ├── main.cpp\n│ ├── schema.cpp\n│ ├── schema.h\n│ ├── resolvers.cpp\n│ └── resolvers.h\n└── vcpkg.json\n\nملف CMakeLists.txt
\ncmake_minimum_required(VERSION 3.14)\nproject(GraphQLCppApi)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nfind_package(graphql-cpp CONFIG REQUIRED)\nfind_package(cpp-httplib CONFIG REQUIRED)\nfind_package(nlohmann_json CONFIG REQUIRED)\n\nadd_executable(graphql_server\n src/main.cpp\n src/schema.cpp\n src/resolvers.cpp\n)\n\ntarget_link_libraries(graphql_server\n graphql-cpp::graphql-cpp\n cpp-httplib::cpp-httplib\n nlohmann_json::nlohmann_json\n)\n\nالآن كل شيء جاهز لكتابة الكود.
\n\n2. تعريف مخطط GraphQL والأنواع
\n\nلنبدأ بإنشاء مخطط لواجهة برمجة تطبيقات بسيطة لإدارة الكتب. سيكون لدينا أنواع Book و Author، بالإضافة إلى الاستعلامات (queries) والتحويرات (mutations).
ملف schema.h
\n#ifndef SCHEMA_H\n#define SCHEMA_H\n\n#include <graphqlcpp/GraphQLSchema.h>\n\nstd::shared_ptr<graphql::GraphQLSchema> createSchema();\n\n#endif\n\nملف schema.cpp
\n#include "schema.h"\n#include "resolvers.h"\n\nstd::shared_ptr<graphql::GraphQLSchema> createSchema() {\n using namespace graphql;\n\n // نوع Author\n auto authorType = object_type("Author", {\n field("id", int_type()),\n field("name", string_type()),\n field("books", list_type(int_type()))\n });\n\n // نوع Book\n auto bookType = object_type("Book", {\n field("id", int_type()),\n field("title", string_type()),\n field("authorId", int_type()),\n field("year", int_type()),\n field("genre", string_type())\n });\n\n // جذر الاستعلام (Query root)\n auto queryType = object_type("Query", {\n field("books", list_type(bookType), {\n argument("genre", string_type(), true) // وسيط اختياري\n }, resolveBooks),\n field("book", bookType, {\n argument("id", int_type(), false) // وسيط إلزامي\n }, resolveBookById),\n field("authors", list_type(authorType), resolveAuthors)\n });\n\n // جذر التحوير (Mutation root)\n auto mutationType = object_type("Mutation", {\n field("addBook", bookType, {\n argument("title", string_type(), false),\n argument("authorId", int_type(), false),\n argument("year", int_type(), false),\n argument("genre", string_type(), false)\n }, resolveAddBook),\n field("deleteBook", bool_type(), {\n argument("id", int_type(), false)\n }, res