Современный C++ в мире API: REST, GraphQL и gRPC на практике

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

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

Начать курс

Работа с API на C++: REST, GraphQL, gRPC

Когда речь заходит о создании или потреблении API, многие разработчики по привычке тянутся к Python, Node.js или Go. Но как быть, если вам нужна максимальная производительность, низкоуровневый контроль над памятью или вы работаете в legacy-системе, где C++ — король? Ответ прост: C++ не просто жив — он процветает в мире API. Давайте разберем три ключевых подхода, которые должен знать каждый C++-разработчик: классический REST, современный GraphQL и высокопроизводительный gRPC.

Эта статья — не сухой справочник, а практическое руководство, написанное для тех, кто хочет писать реальный код. Мы рассмотрим, как эти технологии применяются на C++, приведем примеры с популярными библиотеками и поможем выбрать правильный инструмент для вашей задачи.

1. REST API на C++: классика в современном исполнении

REST (Representational State Transfer) остается самым распространенным стилем API. Его любят за простоту, человекочитаемость JSON и универсальность. На C++ у нас есть несколько мощных инструментов для работы с REST, и один из самых популярных — cpprestsdk (он же Casablanca) от Microsoft.

Пишем REST-клиент на C++

Представьте, что нам нужно получить данные о погоде от публичного API. Вот как это выглядит с cpprestsdk:

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <iostream>

using namespace web;
using namespace web::http;
using namespace web::http::client;

int main() {
    // Создаем HTTP-клиент
    http_client client(U("https://api.openweathermap.org/data/2.5"));

    // Формируем GET-запрос с параметрами
    uri_builder builder(U("/weather"));
    builder.append_query(U("q"), U("Moscow"));
    builder.append_query(U("appid"), U("YOUR_API_KEY"));
    builder.append_query(U("units"), U("metric"));

    // Отправляем запрос и получаем ответ
    client.request(methods::GET, builder.to_string())
        .then([](http_response response) {
            if (response.status_code() == status_codes::OK) {
                return response.extract_json();
            }
            throw std::runtime_error("Failed to fetch data");
        })
        .then([](json::value jsonData) {
            std::cout << "Temperature: " 
                      << jsonData[U("main")][U("temp")].as_double() 
                      << "°C" << std::endl;
        })
        .wait();

    return 0;
}

Ключевые моменты:

  • Асинхронность: cpprestsdk использует PPL (Parallel Patterns Library) и futures, что идеально для C++.
  • Работа с JSON: встроенный парсер json::value позволяет легко манипулировать данными.
  • Кроссплатформенность: библиотека работает на Windows, Linux и macOS.

Когда выбирать REST?

REST на C++ идеален для:

  • Простых CRUD-операций
  • Интеграции с веб-сервисами (соцсети, платежные системы)
  • Прототипирования и микросервисов с невысокой нагрузкой

2. GraphQL: гибкость запросов на C++

GraphQL решает главную проблему REST — overfetching (получение лишних данных) и underfetching (необходимость нескольких запросов для получения полной информации). На C++ для работы с GraphQL чаще всего используют библиотеку cppgraphql или пишут собственный клиент на основе libcurl.

Пример GraphQL-запроса на C++

Допустим, нам нужно получить профиль пользователя и его последние посты — в REST это потребовало бы два запроса, а в GraphQL — один:

#include <iostream>
#include <curl/curl.h>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

int main() {
    CURL *curl = curl_easy_init();
    std::string response;

    if (curl) {
        // GraphQL-запрос
        std::string query = R"({
            "query": "{
                user(id: 42) {
                    name
                    email
                    posts(limit: 5) {
                        title
                        createdAt
                    }
                }
            }"
        })";

        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");

        curl_easy_setopt(curl, CURLOPT_URL, "https://api.example.com/graphql");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        CURLcode res = curl_easy_perform(curl);
        if (res == CURLE_OK) {
            auto jsonResponse = json::parse(response);
            std::cout << "User: " << jsonResponse["data"]["user"]["name"] << std::endl;
            std::cout << "Posts count: " << jsonResponse["data"]["user"]["posts"].size() << std::endl;
        }

        curl_easy_cleanup(curl);
        curl_slist_free_all(headers);
    }
    return 0;
}

Почему это круто?

  • Точность запросов: вы получаете ровно то, что нужно, без лишнего трафика.
  • Снижение нагрузки: один запрос вместо нескольких.
  • Типизация: GraphQL-схема строго типизирована, что упрощает обработку на C++.

Минусы GraphQL на C++

Главный недостаток — отсутствие mature-решений для серверной части. Если вы пишете GraphQL-клиент на C++, libcurl будет лучшим выбором. Для сервера придется использовать интеграцию с Node.js или Python.

3. gRPC: когда скорость критична

gRPC — это флагманский протокол Google для микросервисной архитектуры. Он использует Protocol Buffers (protobuf) для сериализации и HTTP/2 для транспорта. На C++ gRPC работает просто великолепно: минимальные накладные расходы, бинарный протокол и полная поддержка стриминга.

Настройка gRPC на C++

Сначала определим сервис в .proto-файле:

syntax = "proto3";

package weather;

service WeatherService {
    rpc GetForecast (ForecastRequest) returns (ForecastResponse);
}

message ForecastRequest {
    string city = 1;
    int32 days = 2;
}

message ForecastResponse {
    repeated DayForecast forecasts = 1;
}

message DayForecast {
    string date = 1;
    double temperature_max = 2;
    double temperature_min = 3;
}

Теперь напишем сервер на C++:

#include <grpcpp/grpcpp.h>
#include "weather.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::Server                

Блоги

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