GraphQL в C++: библиотека cppgraphqlgen для создания API

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

GraphQL библиотека C++: cppgraphqlgen

cppgraphqlgen — это современная библиотека на C++ для реализации серверной части GraphQL. Она позволяет разработчикам создавать типобезопасные, быстрые и масштабируемые API, используя преимущества статической типизации C++. Библиотека генерирует код на основе схемы GraphQL (.graphql файлов), что минимизирует ручное написание резолверов и снижает вероятность ошибок.

Основные возможности

  • Генерация кода из схемы — на вход подаётся файл schema.graphql, на выходе получаются C++ классы и функции.
  • Типобезопасность — все типы GraphQL (String, Int, Float, Boolean, ID, Enum, Input, Object) компилируются в соответствующие типы C++.
  • Поддержка подписок (Subscriptions) — реализована через WebSocket и асинхронные потоки.
  • Валидация запросов — встроенная проверка синтаксиса и семантики GraphQL-запросов.
  • Интеграция с HTTP — работает поверх любого C++ HTTP-сервера (например, beast из Boost).
  • Поддержка директив — кастомные директивы для расширения функционала.

Установка

Для установки cppgraphqlgen требуется компилятор с поддержкой C++17 и система сборки CMake. Установка через vcpkg или сборка из исходников:

# Через vcpkg
vcpkg install cppgraphqlgen

# Сборка из репозитория
git clone https://github.com/microsoft/cppgraphqlgen.git
cd cppgraphqlgen
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --target install

Пример использования

Рассмотрим простой пример: создадим схему GraphQL для получения информации о пользователе и книге. Сначала определим схему schema.graphql:

type Query {
  user(id: ID!): User
  book(id: ID!): Book
}

type User {
  id: ID!
  name: String!
  email: String
}

type Book {
  id: ID!
  title: String!
  author: String!
}

После генерации кода (команда graphqlgen) получаем файл Generated.h. Теперь напишем резолверы на C++:

#include "Generated.h"
#include <unordered_map>

// Пример данных (в реальном проекте — БД)
std::unordered_map<std::string, User> users = {
    {"1", {"1", "Alice", "alice@example.com"}},
    {"2", {"2", "Bob", nullptr}}
};

std::unordered_map<std::string, Book> books = {
    {"10", {"10", "C++ Primer", "Lippman"}},
    {"20", {"20", "Effective Modern C++", "Meyers"}}
};

// Резолвер для Query.user
User resolveGetUser(const std::string& id) {
    auto it = users.find(id);
    if (it != users.end()) {
        return it->second;
    }
    throw std::runtime_error("User not found");
}

// Резолвер для Query.book
Book resolveGetBook(const std::string& id) {
    auto it = books.find(id);
    if (it != books.end()) {
        return it->second;
    }
    throw std::runtime_error("Book not found");
}

Теперь настраиваем сервер и запускаем обработку запросов:

#include <graphqlservice/GraphQLService.h>
#include <beast/http.hpp>

int main() {
    // Создаём сервис со схемой
    auto service = std::make_shared<graphql::service::GraphQLService>();

    // Регистрируем резолверы
    service->addResolver("Query", "user", resolveGetUser);
    service->addResolver("Query", "book", resolveGetBook);

    // Запускаем HTTP-сервер (упрощённо)
    http::server server("0.0.0.0", 8080, service);
    server.run();

    return 0;
}

Обработка ошибок и валидация

Библиотека автоматически проверяет корректность входящих запросов. Если резолвер выбрасывает исключение, cppgraphqlgen преобразует его в GraphQL-ошибку с соответствующим кодом. Пример обработки:

// Кастомное исключение
class NotFoundException : public std::exception {
    const char* what() const noexcept override {
        return "Resource not found";
    }
};

// Резолвер с обработкой
User resolveGetUserSafe(const std::string& id) {
    auto it = users.find(id);
    if (it == users.end()) {
        throw NotFoundException();
    }
    return it->second;
}

Преимущества и недостатки

Плюсы:

  • Полная типобезопасность на

Рекомендаций