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

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

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

Начать курс

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

C++ традиционно ассоциируется с системным программированием, играми и высоконагруженными приложениями. Однако, современный C++ (начиная со стандартов C++11/17/20) предоставляет все необходимые инструменты для быстрой разработки веб-сервисов. Написание REST API на C++ может быть оправдано, когда требуется максимальная производительность, низкое потребление памяти или интеграция с существующим C++ кодом (например, библиотеками компьютерного зрения или численных расчетов).

В этом руководстве мы создадим полноценный REST API на C++ за 30 минут. Для этого мы используем легковесную и элегантную библиотеку Crow. Она не требует сложной настройки, поддерживает маршрутизацию, JSON (через json.hpp) и middleware. К концу статьи у вас будет работающий сервер с тремя эндпоинтами.

Шаг 1: Настройка окружения и установка Crow

Для работы нам понадобится компилятор с поддержкой C++17 (g++ 7+, clang 5+ или MSVC 2017+) и система сборки CMake. Crow — это "header-only" библиотека, что упрощает установку: достаточно скачать один заголовочный файл.

Установка

  1. Скачайте последнюю версию Crow с GitHub (или используйте git clone).
  2. Скопируйте папку include в ваш проект.
  3. Установите nlohmann/json (также header-only) для работы с JSON.

Структура проекта

my_rest_api/
├── CMakeLists.txt
├── main.cpp
└── include/
    ├── crow.h
    └── json.hpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(my_rest_api)

set(CMAKE_CXX_STANDARD 17)

include_directories(include)

add_executable(my_rest_api main.cpp)
target_link_libraries(my_rest_api pthread)

Сборка: mkdir build && cd build && cmake .. && make

Шаг 2: Создание базового сервера и маршрутов

Crow использует простой DSL для определения маршрутов. Давайте создадим сервер, который слушает порт 8080 и обрабатывает GET и POST запросы.

Базовый код сервера

#include "crow.h"
#include <string>

int main() {
    crow::SimpleApp app;

    // Простой GET маршрут
    CROW_ROUTE(app, "/")([](){
        return "Добро пожаловать в REST API на C++!";
    });

    // GET с параметром пути
    CROW_ROUTE(app, "/user/<int>")([](int user_id){
        return crow::response("ID пользователя: " + std::to_string(user_id));
    });

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

Этот код создает два эндпоинта. crow::SimpleApp — основной класс приложения. Метод multithreaded() включает обработку запросов в пуле потоков. Запустите сервер и проверьте в браузере http://localhost:8080/.

Типы параметров в маршрутах

Crow поддерживает следующие типы параметров в пути:

  • <int> — целое число
  • <string> — строка
  • <path> — остаток пути (например, /files/<path>)
  • <float> — число с плавающей точкой

Шаг 3: Работа с JSON и POST запросами

Настоящий REST API должен уметь принимать и возвращать JSON. Подключим nlohmann/json и реализуем CRUD-подобные операции.

Пример: Простая "База данных" в памяти

#include "crow.h"
#include "json.hpp"
#include <unordered_map>
#include <memory>

using json = nlohmann::json;

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

std::unordered_map<int, std::shared_ptr<Task>> tasks;
int next_id = 1;

int main() {
    crow::SimpleApp app;

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

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

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

    // GET /tasks/<int> — получить задачу по ID
    CROW_ROUTE(app, "/tasks/<int>")([](int id){
        if (tasks.count(id) == 0) {
            return crow::response(404, "Задача не найдена");
        }
        auto task = tasks[id];
        json j = {{"id", task->id}, {"title", task->title}, {"completed", task->completed}};
        return crow::response(j.dump());
    });

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

Здесь мы используем std::unordered_map для хранения задач. Обратите внимание на обработку POST: мы читаем тело запроса (req.body), парсим JSON и возвращаем ответ с кодом 201 (Created).

Тестирование через curl

# Создать задачу
curl -X POST http://localhost:8080/tasks -H "Content-Type: application/json" -d '{"title":"Изучить C++","completed":false}'

# Получить все задачи
curl http://localhost:8080/tasks

# Получить задачу по ID
curl http://localhost:8080/tasks/1

Шаг 4: Обработка ошибок и CORS (дополнительно)

Блоги

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