本文作者:icy

Oat++:现代C++高性能Web框架入门指南

icy 02-28 15 抢沙发
Oat++:现代C++高性能Web框架入门指南摘要: Oat++:现代C++高性能Web框架入门指南 什么是Oat++? Oat++(也称为oatpp)是一个轻量级、高性能的现代C++ Web框架,专为构建可扩展的RESTful AP...

Oat++:现代C++高性能Web框架入门指南

Oat++:现代C++高性能Web框架入门指南

什么是Oat++?

Oat++(也称为oatpp)是一个轻量级、高性能的现代C++ Web框架,专为构建可扩展的RESTful API和Web服务而设计。它采用纯C++17标准编写,不依赖任何外部库,提供了简洁直观的API,让开发者能够快速构建高效的网络应用程序。

核心特性

1. 零依赖设计

Oat++完全基于C++标准库构建,无需安装额外的第三方依赖,简化了部署和跨平台开发。

2. 高性能异步I/O

内置基于事件循环的异步I/O模型,支持高并发连接处理,适合构建高性能服务器应用。

3. 类型安全的API

利用C++模板和现代C++特性,提供编译时类型检查,减少运行时错误。

4. 简洁的声明式API

通过简单的代码即可定义REST端点,自动处理HTTP请求/响应序列化。

5. 跨平台支持

支持Linux、macOS、Windows等主流操作系统。

快速开始

安装Oat++

text
# 使用vcpkg安装
vcpkg install oatpp

# 或使用CMake直接从源码构建
git clone https://github.com/oatpp/oatpp.git
cd oatpp
mkdir build && cd build
cmake ..
make install

第一个Oat++应用

下面是一个简单的”Hello World” REST API示例:

text
#include "oatpp/web/server/HttpConnectionHandler.hpp"
#include "oatpp/network/Server.hpp"
#include "oatpp/network/tcp/server/ConnectionProvider.hpp"
#include "oatpp/web/server/HttpRouter.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "oatpp/core/macro/component.hpp"

#include OATPP_CODEGEN_BEGIN(DTO)

// 定义数据传输对象(DTO)
class MessageDto : public oatpp::DTO {
  DTO_INIT(MessageDto, DTO)
  
  DTO_FIELD(String, message);
  DTO_FIELD(Int32, status);
};

#include OATPP_CODEGEN_END(DTO)

// 创建控制器
class MyController : public oatpp::web::server::api::ApiController {
public:
  MyController(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
    : oatpp::web::server::api::ApiController(objectMapper) {}
  
public:
  
  // 定义端点
  ENDPOINT("GET", "/hello", getHello) {
    auto dto = MessageDto::createShared();
    dto->message = "Hello World!";
    dto->status = 200;
    return createDtoResponse(Status::CODE_200, dto);
  }
  
  ENDPOINT("GET", "/hello/{name}", getHelloWithName,
           PATH(String, name)) {
    auto dto = MessageDto::createShared();
    dto->message = "Hello " + name + "!";
    dto->status = 200;
    return createDtoResponse(Status::CODE_200, dto);
  }
};

// 应用组件配置
class AppComponent {
public:
  
  // 创建连接提供者
  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, serverConnectionProvider)([] {
    return oatpp::network::tcp::server::ConnectionProvider::createShared({"0.0.0.0", 8000, oatpp::network::Address::IP_4});
  }());
  
  // 创建路由器
  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, httpRouter)([] {
    return oatpp::web::server::HttpRouter::createShared();
  }());
  
  // 创建连接处理器
  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, serverConnectionHandler)([] {
    OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
    return oatpp::web::server::HttpConnectionHandler::createShared(router);
  }());
  
  // 创建对象映射器
  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper)([] {
    return oatpp::parser::json::mapping::ObjectMapper::createShared();
  }());
};

// 主函数
void run() {
  // 注册组件
  AppComponent components;
  
  // 获取路由器并添加控制器
  OATPP_COMPONENT(std::shared_ptr<oatpp::web::server::HttpRouter>, router);
  
  auto controller = std::make_shared<MyController>(
    OATPP_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper)
  );
  
  router->addController(controller);
  
  // 获取连接处理器
  OATPP_COMPONENT(std::shared_ptr<oatpp::network::ConnectionHandler>, connectionHandler);
  
  // 获取连接提供者
  OATPP_COMPONENT(std::shared_ptr<oatpp::network::ServerConnectionProvider>, connectionProvider);
  
  // 创建服务器
  oatpp::network::Server server(connectionProvider, connectionHandler);
  
  OATPP_LOGI("MyApp", "Server running on port %s", connectionProvider->getProperty("port").toString()->c_str());
  
  // 运行服务器
  server.run();
}

int main() {
  // 初始化环境
  oatpp::base::Environment::init();
  
  // 运行应用
  run();
  
  // 清理环境
  oatpp::base::Environment::destroy();
  
  return 0;
}

CMakeLists.txt 配置

text
cmake_minimum_required(VERSION 3.10)
project(my_oatpp_app)

set(CMAKE_CXX_STANDARD 17)

# 查找Oat++包
find_package(oatpp REQUIRED)

# 添加可执行文件
add_executable(${PROJECT_NAME} main.cpp)

# 链接Oat++库
target_link_libraries(${PROJECT_NAME}
    oatpp
    oatpp-swagger
    pthread
)

实用示例:TODO列表API

下面是一个更完整的示例,展示如何构建一个简单的TODO列表REST API:

text
#include "oatpp/web/server/HttpConnectionHandler.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include <unordered_map>
#include <mutex>

#include OATPP_CODEGEN_BEGIN(DTO)

// TODO项DTO
class TodoDto : public oatpp::DTO {
  DTO_INIT(TodoDto, DTO)
  
  DTO_FIELD(Int64, id);
  DTO_FIELD(String, title);
  DTO_FIELD(String, description);
  DTO_FIELD(Boolean, completed);
  DTO_FIELD(String, createdAt);
};

// 创建TODO请求DTO
class CreateTodoDto : public oatpp::DTO {
  DTO_INIT(CreateTodoDto, DTO)
  
  DTO_FIELD(String, title);
  DTO_FIELD(String, description);
};

// 更新TODO请求DTO
class UpdateTodoDto : public oatpp::DTO {
  DTO_INIT(UpdateTodoDto, DTO)
  
  DTO_FIELD(String, title);
  DTO_FIELD(String, description);
  DTO_FIELD(Boolean, completed);
};

#include OATPP_CODEGEN_END(DTO)

// 简单的内存存储
class TodoStore {
private:
  std::unordered_map<int64_t, std::shared_ptr<TodoDto>> todos;
  int64_t nextId = 1;
  std::mutex mutex;
  
public:
  std::shared_ptr<TodoDto> createTodo(const std::shared_ptr<CreateTodoDto>& dto) {
    std::lock_guard<std::mutex> lock(mutex);
    
    auto todo = TodoDto::createShared();
    todo->id = nextId++;
    todo->title = dto->title;
    todo->description = dto->description;
    todo->completed = false;
    todo->createdAt = "2024-01-01T00:00:00Z"; // 实际应用中应该使用真实时间
    
    todos[todo->id] = todo;
    return todo;
  }
  
  std::shared_ptr<TodoDto> getTodo(int64_t id) {
    std::lock_guard<std::mutex> lock(mutex);
    auto it = todos.find(id);
    if (it != todos.end()) {
      return it->second;
    }
    return nullptr;
  }
  
  std::vector<std::shared_ptr<TodoDto>> getAllTodos() {
    std::lock_guard<std::mutex> lock(mutex);
    std::vector<std::shared_ptr<TodoDto>> result;
    for (const auto& pair : todos) {
      result.push_back(pair.second);
    }
    return result;
  }
  
  bool updateTodo(int64_t id, const std::shared_ptr<UpdateTodoDto>& dto) {
    std::lock_guard<std::mutex> lock(mutex);
    auto it = todos.find(id);
    if (it != todos.end()) {
      if (dto->title) it->second->title = dto->title;
      if (dto->description) it->second->description = dto->description;
      if (dto->completed) it->second->completed = dto->completed;
      return true;
    }
    return false;
  }
  
  bool deleteTodo(int64_t id) {
    std::lock_guard<std::mutex> lock(mutex);
    return todos.erase(id) > 0;
  }
};

// TODO控制器
class TodoController : public oatpp::web::server::api::ApiController {
private:
  TodoStore todoStore;
  
public:
  TodoController(OATPP_COMPONENT(std::shared_ptr<ObjectMapper>, objectMapper))
    : oatpp::web::server::api::ApiController(objectMapper) {}
  
public:
  
  // 创建TODO
  ENDPOINT("POST", "/todos", createTodo,
           BODY_DTO(std::shared_ptr<CreateTodoDto>, dto)) {
    auto todo = todoStore.createTodo(dto);
    return createDtoResponse(Status::CODE_201, todo);
  }
  
  // 获取所有TODO
  ENDPOINT("GET", "/todos", getAllTodos) {
    auto todos = todoStore.getAllTodos();
    auto response = oatpp::web::protocol::http::outgoing::Response::createShared(
      Status::CODE_200,
      getDefaultObjectMapper()->writeToString(todos)
    );
    response->putHeader("Content-Type", "application/json");
    return response;
  }
  
  // 获取单个TODO
  ENDPOINT("GET", "/todos/{id}", getTodo,
           PATH(Int64, id)) {
    auto todo = todoStore.getTodo(id);
    if (todo) {
      return createDtoResponse(Status::CODE_200, todo);
    }
    return createResponse(Status::CODE_404, "Todo not found");
  }
  
  // 更新TODO
  ENDPOINT("PUT", "/todos/{id}", updateTodo,
           PATH(Int64, id),
           BODY_DTO(std::shared_ptr<UpdateTodoDto>, dto)) {
    if (todoStore.updateTodo(id, dto)) {
      auto todo = todoStore.getTodo(id);
      return createDtoResponse(Status::CODE_200, todo);
    }
    return createResponse(Status::CODE_404, "Todo not found");
  }
  
  // 删除TODO
  ENDPOINT("DELETE", "/todos/{id}", deleteTodo,
           PATH(Int64, id)) {
    if (todoStore.deleteTodo(id)) {
      return createResponse(Status::CODE_204, "");
    }
    return createResponse(Status::CODE_404, "Todo not found");
  }
};

高级特性

中间件支持

Oat++支持中间件模式,可以轻松添加认证、日志记录等功能:

text
class LoggingMiddleware : public oatpp::web::server::handler::RequestInterceptor {
public:
  std::shared_ptr<OutgoingResponse> intercept(const std::shared_ptr<IncomingRequest>& request) override {
    OATPP_LOGI("Request", "%s %s", 
               request->getStartingLine().method.toString()->c_str(),
               request->getStartingLine().path.toString()->c_str());
    return nullptr; // 继续处理请求
  }
};

数据库集成

Oat++可以轻松集成各种数据库。以下是使用oatpp-orm和oatpp-sqlite的示例:

text
#include "oatpp-sqlite/orm.hpp"

#include OATPP_CODEGEN_BEGIN(DTO)

class UserDto : public oatpp::DTO {
  DTO_INIT(UserDto, DTO)
  DTO_FIELD(Int64, id);
  DTO_FIELD(String, username);
  DTO_FIELD(String, email);
  DTO_FIELD(String, created_at);
};

#include OATPP_CODEGEN_END(DTO)

class DatabaseComponent {
public:
  
  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::provider::Provider<oatpp::sqlite::Connection>>, dbConnectionProvider)([] {
    auto connectionProvider = std::make_shared<oatpp::sqlite::ConnectionProvider>("test.db");
    return oatpp::sqlite::ConnectionPool::createShared(connectionProvider, 10);
  }());
  
  OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::sqlite::Executor>, dbExecutor)([] {
    OATPP_COMPONENT(std::shared_ptr<oatpp::provider::Provider<oatpp::sqlite::Connection>>, connectionProvider);
    return std::make_shared<oatpp::sqlite::Executor>(connectionProvider);
  }());
};

性能优势

Oat++在设计上注重性能: - 零拷贝数据序列化 - 高效的内存管理 - 基于事件循环的异步处理 - 最小化的运行时开销

适用场景

  1. 高性能API服务器 - 需要处理大量并发请求的REST API
  2. 微服务架构 - 轻量级服务间的通信
  3. 嵌入式系统 - 资源受限环境中的Web服务
  4. 实时应用 - 需要低延迟响应的应用

总结

Oat++为C++开发者提供了一个现代化、高性能的Web开发框架。它结合了现代C++的最佳实践和Web开发的需求,使得构建高性能网络应用变得更加简单和高效。无论是构建简单的REST API还是复杂的企业级应用,Oat++都能提供强大的支持。

通过其简洁的API设计、零依赖架构和出色的性能表现,Oat++正在成为C++ Web开发领域的重要选择之一。如果你正在寻找一个既保持C++性能优势又提供现代Web开发体验的框架,Oat++绝对值得尝试。

学习资源

oatpp_20260204065657.zip
类型:压缩文件|已下载:0|下载方式:免费下载
立即下载
文章版权及转载声明

作者:icy本文地址:https://www.zelig.cn/2026/02/275.html发布于 02-28
文章转载或复制请以超链接形式并注明出处软角落-SoftNook

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

验证码

评论列表 (暂无评论,15人围观)参与讨论

还没有评论,来说两句吧...