Как написать REST API на C++ за 30 минут: на практике

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

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

Начать курс

Введение: зачем писать REST API на C++?

REST API (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов распределённого приложения в сети. Обычно для написания REST API выбирают Python (Flask, FastAPI), JavaScript (Express.js) или Java. Однако C++ остаётся незаслуженно обойдённым вниманием. А зря.

Современные библиотеки, такие как Crow, cpp-httplib и Drogon, позволяют создавать высокопроизводительные REST API на C++ буквально за полчаса. Благодаря скорости работы C++ и минимальному потреблению памяти, такие API идеально подходят для:

  • микросервисов с высокими требованиями к производительности;
  • встраиваемых систем и IoT-устройств;
  • обработки большого числа параллельных запросов;
  • реализации шлюзов и прокси-серверов.

В этой статье мы на практике создадим простое REST API на C++ с использованием библиотеки Crow. Вы увидите, что это не сложнее, чем на Python, а по скорости работы — в разы быстрее.

Настройка окружения и установка библиотеки Crow

Для нашего проекта мы будем использовать Crow — минималистичный и очень быстрый C++ микро-веб-фреймворк. Он поддерживает маршрутизацию, middleware, JSON-сериализацию и работает на Windows, Linux и macOS.

Что потребуется

  • Компилятор C++17 или новее (GCC 8+, Clang 7+, MSVC 2019+);
  • CMake версии 3.14+;
  • Библиотека asio (устанавливается автоматически с Crow);
  • Библиотека nlohmann/json (для работы с JSON).

Установка Crow

Crow — header-only библиотека. Это значит, что вам не нужно её компилировать — достаточно скопировать заголовочные файлы в проект. Самый простой способ — через CMake FetchContent.

Создайте структуру проекта:

rest-api-cpp/
├── CMakeLists.txt
├── src/
│   └── main.cpp
└── include/

Содержимое файла CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(rest_api_cpp)

set(CMAKE_CXX_STANDARD 17)

# Подключаем Crow
include(FetchContent)
FetchContent_Declare(
  crow
  GIT_REPOSITORY https://github.com/ipkn/crow.git
  GIT_TAG master
)
FetchContent_MakeAvailable(crow)

# Подключаем nlohmann/json
FetchContent_Declare(
  json
  GIT_REPOSITORY https://github.com/nlohmann/json.git
  GIT_TAG v3.11.2
)
FetchContent_MakeAvailable(json)

add_executable(rest_api src/main.cpp)
target_link_libraries(rest_api PRIVATE Crow::Crow nlohmann_json::nlohmann_json)

После этого выполните:

mkdir build && cd build
cmake ..
make

Всё готово к написанию кода.

Создание базового REST API на C++ с помощью Crow

Напишем простое API для управления списком задач (Task Manager). Оно будет поддерживать четыре основных HTTP-метода: GET, POST, PUT, DELETE.

Каркас сервера и GET-эндпоинт

#include <crow.h>
#include <nlohmann/json.hpp>
#include <vector>
#include <string>

using json = nlohmann::json;

struct Task {
    int id;
    std::string title;
    bool completed;
};

std::vector<Task> tasks = {
    {1, "Изучить Crow", false},
    {2, "Написать REST API", false}
};
int next_id = 3;

int main() {
    crow::SimpleApp app;

    // GET /tasks — получить все задачи
    CROW_ROUTE(app, "/tasks")
    .methods("GET"_method)
    ([](){
        json j = json::array();
        for (const auto& t : tasks) {
            j.push_back({{"id", t.id}, {"title", t.title}, {"completed", t.completed}});
        }
        return crow::response(j.dump());
    });

    app.port(8080).multithreaded().run();
}

Этот код запускает HTTP-сервер на порту 8080. При GET-запросе к /tasks возвращается JSON-массив со всеми задачами.

POST — добавление новой задачи

// POST /tasks — создать новую задачу
CROW_ROUTE(app, "/tasks")
.methods("POST"_method)
([](const crow::request& req){
    auto body = json::parse(req.body);
    Task new_task;
    new_task.id = next_id++;
    new_task.title = body["title"];
    new_task.completed = false;
    tasks.push_back(new_task);

    json resp = {{"id", new_task.id}, {"title", new_task.title}, {"completed", new_task.completed}};
    return crow::response(201, resp.dump());
});

Обратите внимание: мы возвращаем HTTP-статус 201 (Created) и JSON с данными созданной задачи.

PUT — обновление задачи по ID

// PUT /tasks/<int> — обновить задачу
CROW_ROUTE(app, "/tasks/<int>")
.methods("PUT"_method)
([](const crow::request& req, int id){
    auto it = std::find_if(tasks.begin(), tasks.end(), [id](const Task& t){ return t.id == id; });
    if (it == tasks.end()) {
        return crow::response(404, "Task not found");
    }

    auto body = json::parse(req.body);
    if (body.contains("title")) it->title = body["title"];
    if (body.contains("completed")) it->completed = body["completed"];

    json resp = {{"id", it->id}, {"title", it->title}, {"completed", it->completed}};
    return crow::response(resp.dump());
});

DELETE — удаление задачи

// DELETE /tasks/<int> — удалить задачу
CROW_ROUTE(app, "/tasks/<int>")
.methods("DELETE"_method)
([](int id){
    auto it = std::remove_if(tasks.begin(), tasks.end(), [id](const Task& t){ return t.id == id; });
    if (it == tasks.end()) {
        return crow::response(404, "Task not found");
    }
    tasks.erase(it, tasks.end());
    return crow::response(204);
});

Метод DELETE возвращает статус 204 (No Content) — это стандарт для успешного удаления.

Тестирование API и типичные

Блоги

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