GraphQL 对比 REST 在 C++ 中:为高负载系统选择 API
\n\nREST 和 GraphQL 之间的争论在任何编程语言中都没有平息。但当涉及到 C++——这种每个字节和每微秒都至关重要的语言时——讨论就有了特殊的意味。许多人认为 C++ 只用于底层驱动和游戏引擎,而 Web API 是用 Python、Go 或 Rust 编写的。但事实并非如此。C++ 被用于创建高负载后端、金融系统微服务和物联网平台,在这些场景中速度至关重要。
\n\n在本文中,我们将分析哪种更适合 C++ 项目:经典的 REST 还是现代的 GraphQL。没有废话——只有真实的 C++ 代码、基准测试和实用建议。
\n\nC++ 中的 REST:行之有效的经典方案
\n\nREST 是一种架构风格,而非协议。在 C++ 中,它通过 HTTP 服务器实现。最流行的库是 CrowCpp、Drogon 和 Pistache。它们轻量、快速,并能快速搭建 API。
\n\n以下是在 C++ 中使用 CrowCpp 实现的一个简单 REST 端点示例:
\n\n#include "crow.h"\n\nstruct User {\n int id;\n std::string name;\n std::string email;\n};\n\nint main() {\n crow::SimpleApp app;\n\n CROW_ROUTE(app, "/user/<int>")\n ([](int user_id) {\n // 模拟数据库查询\n User user{user_id, "Alice", "alice@example.com"};\n \n crow::json::wvalue x;\n x["id"] = user.id;\n x["name"] = user.name;\n x["email"] = user.email;\n return x;\n });\n\n app.port(8080).multithreaded().run();\n}\n\n\nC++ 中 REST 的优点显而易见:最小的开销、可预测的 HTTP 方法(GET、POST、PUT、DELETE)以及大量现成的工具。你只需编写一个函数,将其绑定到 URL 上,就完成了。对于简单的 CRUD 操作,REST 仍然是王者。
\n\n但也有缺点。在实际项目中,经常会出现 过度获取(获取多余数据)和 获取不足(需要多次请求)的问题。例如,要获取一个用户及其最近的订单,你需要两个请求:/user/1 和 /orders?user_id=1。在 C++ 中这可以解决,但代价是在后端编写额外的代码。
C++ 中的 GraphQL:带类型化的灵活性
\n\nGraphQL 是一种查询语言,允许客户端只请求所需的内容。对于 C++,有成熟的库:cppgraphqlgen(来自微软)、taoPQ 和 Drogon GraphQL。它们从 GraphQL 模式生成 C++ 代码,从而在编译阶段提供严格的类型化。
\n\n以下是在 C++ 中使用 cppgraphqlgen 的 GraphQL 解析器示例:
#include "graphqlservice/GraphQLService.h"\n#include "UserSchema.h" // 从 schema.graphql 生成\n\nclass UserResolver : public graphql::User::Object {\npublic:\n std::shared_ptr<graphql::User::User> getUser(int32_t id) override {\n auto user = std::make_shared<graphql::User::User>();\n user->getId() = id;\n user->getName() = "Alice";\n user->getEmail() = "alice@example.com";\n return user;\n }\n};\n\nint main() {\n auto service = std::make_shared<graphql::User::Service>(std::make_shared<UserResolver>());\n // 启动 HTTP 服务器(例如,通过 Crow)\n}\n\n\nGraphQL 在 C++ 中的主要优势是 类型安全。如果你更改了模式,编译器会立即指出所有需要修改解析器的地方。没有“意外字段”的运行时错误。对于模型数据频繁变更的项目,这可以节省数小时的调试时间。
\n\n然而,灵活性是有代价的。GraphQL 查询需要在服务器端进行解析和验证,这会增加 CPU 开销。在 C++ 中,这不像在 Python 中那么严重,但对于每秒数百万请求的系统来说,这仍然是一个需要考虑的因素。