如何使用C++语言和JSON解析器创建Restful Web服务

47

我正在从事嵌入式Linux项目,希望在我的Linux定制板上运行Restful Web服务。

我的目标是发送/接收数据(以JSON格式)到/来自Web服务器(httpd服务器)。

另外,我想使用C++语言创建这些Restful Web服务。

请看下面关于我需要Linux定制板的Restful Web服务的想法。

  1. 首先,我将通过在我的Linux板上运行的httpd服务器发送HTTP请求,并发送JSON格式数据。

  2. 然后,我想要创建一个二进制文件或服务器,它用C++语言实现了这个Restful Web服务,用于处理HTTP请求。

  3. 接着,这个C++二进制文件将向httpd服务器发送响应,以便在Web浏览器上显示。

有人知道如何使用C++语言创建Restful Web服务的示例或想法吗?

对Restful的任何帮助都会很受欢迎。

有人知道ffead及其功能,是否满足我的Restful Web服务要求吗?

10个回答

39

Restbed可以满足您的需求,除了JSON解析器之外。但是,将其与许多现有的C++JSON实现之一相结合只需要很少的工作。

#include <memory>
#include <string>
#include <cstdlib>
#include <sstream>
#include <jsonbox.h>
#include <restbed>

using namespace std;
using namespace restbed;

void get_method_handler( const shared_ptr< Session > session )
{
    const auto request = session->get_request( );

    size_t content_length = request->get_header( "Content-Length", 0 );

    session->fetch( content_length, [ ]( const shared_ptr< Session >& session, const Bytes& body )
    {
        JsonBox::Value json;
        json.loadFromString( string( body.begin( ), body.end( ) ) );

        //perform awesome solutions logic...

        stringstream stream;
        json.writeToStream( stream );
        string response_body = stream.str( );

        session->close( OK, response_body, { { "Content-Length", ::to_string( response_body.length( ) }, { "Content-Type": "application/json" } } );
    } );
}

int main( const int, const char** )
{
    auto resource = make_shared< Resource >( );
    resource->set_path( "/resource" );
    resource->set_method_handler( "GET", get_method_handler );

    auto settings = make_shared< Settings >( );
    settings->set_port( 1984 );
    settings->set_default_header( "Connection", "close" );

    Service service;
    service.publish( resource );
    service.start( settings );

    return EXIT_SUCCESS;
}

替代的RESTful框架

替代的JSON框架


1
如果您正在Linux上进行开发,请小心,因为SSL仅在Windows系统上实现。如果这不是问题,在我看来,Casablanca是C++中最好的API Rest框架。 - GutiMac
1
@GutiMac 自Restbed 2.5版本以来,它已经在BSD、Mac、Linux和Windows系统上实现了SSL功能。如果您对其使用有困难,请在项目页面上提出问题,我们很乐意为您提供帮助。 - Ben Crowhurst
3
是的,Casablanca是一个非常好的框架...它真的很全面,但SSL对我的软件有所限制,因此我更换了框架。是的,我用过restbed...但是“AGPL”许可证不适合我...所以我认为最好的选择是“POCO C++网络库”,它非常实用,你可以轻松创建带有SSL的应用程序。我想知道您对此的意见。 - GutiMac
1
C++ REST SDK支持Linux、OS X、Unix、iOS和Android,除了Windows。如果它从Casablanca改名,那么它必须已经被重新编写以支持额外的平台。那些声称它只支持Windows的评论似乎不再正确。 - Mr Z
2
截至2021年,可以认为C++ REST SDK已死!它不再得到积极开发,因此用户在使用它之前必须三思而后行。 - Hossein
显示剩余4条评论

6
我知道这有点晚了,但是一两年前出现了一些新的东西。
如果你对高性能异步编程感兴趣,可以考虑使用boost::beast。它是在boost::asio(通用的tcp/udp和i/o库)之上的一层,具有http(s)和websocket服务器/客户端。
请记住,这些适用于性能和多线程中的完全自由(如果你有一个可以承受的服务器,你可以在成千上万个线程上运行你的服务器,并且几乎完美地缓存),但他们有陡峭的学习曲线。只有当你需要对所有事情都有绝对控制时才这样做!

6

2
你如何将nlohmann/json与oatpp集成?你是否在DTO中将有效载荷作为oatpp::String传输,然后使用nlohmann/json解析它?还是直接将nlohmann/json对象包含为DTO的成员? - ktnr

3
如果您正在使用Apache2或Nginx作为Web服务器,并想在其上部署RESTful JSON Web服务,请尝试ngrest。它易于使用且速度快。
为了表示C ++中的JSON,ngrest使用标准C ++类型(通用类型,C ++结构体,typedefs,STL容器等)。也可以访问原始JSON。可选地,您可以使用ngrest-db扩展访问DBMS。 创建C ++服务的典型工作流程示例: 1)创建服务(可以实现为h / cpp或单个hpp文件):
ngrest create -d hpp Users

2)实现数据结构和操作(资源)。编辑users/users/src/Users.hpp,如下:

// a structure to represent data in JSON
struct User {
    int id;
    std::string name;
    std::string email;
};

// *location: /users
class Users: public ngrest::Service
{
public:
    // *method: POST
    int add(const User& user) {
        return Db::inst().users().insert(user).lastInsertId();
    }

    // *location: /{id}
    User get(int id) {
        return Db::inst().users().selectOne("id = ?", id);
    }

    // *method: DELETE
    void remove(int id) {
        Db::inst().users().deleteWhere("id = ?", id);
    }
};

3) 运行您的服务进行测试:

cd users
ngrest

4) 使用服务测试器测试您的RESTful Web服务: http://localhost:9098/ngrest/service/users

5) 将您的Web服务库部署到运行ngrest的Web服务器上。


4
你应该披露你是ngrest的作者。 - Joe Schrag
很好。他并没有试图隐藏这种关系。我喜欢ngrest的Apache 2.0许可证。 - CaTx
只是想说一下,我尝试了ngrest并成功在本地运行了一些东西。然而,该服务无法从另一台计算机访问。我尝试左右寻找解决方案,但没有找到。在Github页面上提交工单也没有帮助。我正在切换到Pistache,它似乎更强大,文档可能更好。我希望这能节省人们的时间。 - CaTx
我一直在尝试使用ngrest,并且按照你的示例成功运行了服务,但是我想在codeblocks中使用它,因为我已经编写了我的程序。你能否指导我如何在codeblocks中使用ngrest的教程?目前我正在ubuntu上尝试这个。 - Thomas Williams

3
如果您正在构建RESTful服务客户端,则应考虑使用类库,例如Casablanca(由Microsoft维护,是访问RESTful API的跨平台解决方案)https://github.com/Microsoft/cpprestsdk
否则,您也可以使用libcurl https://curl.haxx.se/libcurl 对于curl,已经有了C++绑定。根据您的开发板,可能已经安装了libcurl。您只需要使用C++绑定即可。
这两个库都处理http/https。libcurl不提供json解析器,但您可以轻松地将其与任何可用的C++ json解析器结合使用。Casablanca完整且建立在异步模型上。但它依赖于Boost库。尽管如此,我已成功地在Intel Edison板上使用过。

2

2

如果需要以JSON格式发送/接收数据,请尝试使用jsoncpp


2
使用嵌入式Web服务器,例如Mongoose、CivetWeb或NXWeb。(有关更多详细信息,请参见此帖子)通常这些很容易嵌入到您的应用程序中,然后您只需要一个JSON库来解析/创建Web服务器路由处理程序中的JSON数据。毕竟,REST只是HTTP请求,因此使用上述任何一种方法都很容易实现。

1
以上所有的Web服务器是独立的还是不是?它能够嵌入到httpd Web服务器中吗?因为我只想使用httpd Web服务器来创建Restful Web服务,使用C++语言和JSON解析器将HTTP请求从JSON解析为C++,反之亦然。 - Ritesh Prajapati
1
不是的。mongoose只是一个C文件,你需要将其编译到你的项目中。加入两行代码进行初始化和启动,你的程序就可以监听和处理HTTP请求了。再添加一个函数来响应每个URL路由,就完成了。你不需要使用单独的httpd服务。 - gbjbaanb

1

你最好使用FastCGI创建一个模块来与你的Web服务器进行接口。这样做可以避免你自己实现HTTP服务器。


你有没有关于如何使用FastCGI创建Restful Web服务的链接? - Ritesh Prajapati
这只是谜题的一部分。因此,请阅读规格并自己实现它。 - doron

1

有一些框架,比如CppCMS,它们内嵌了自己的HTTP服务器,因此您可能不需要像Apache httpd那样重量级的东西。

我假设您的REST服务不会承受太大的负载。

此外,CppCMS支持JSON,详情请见http://cppcms.com/wikipp/en/page/cppcms_1x_json


CppCMS仅适用于C++和JSON解析。我需要创建可读取HTTP请求并向HTTP发送响应的Restful Web服务。我还想将这些Restful服务创建为C++语言。因此,HTTP请求以JSON格式传入。然后将其转换为C++并从Restful Web服务进行处理。然后再将其转换为JSON格式,并将该响应发送回httpd服务器以显示输出。 - Ritesh Prajapati
@RiteshPrajapati,“CppCMS仅适用于C++和JSON解析”我不确定你的意思。CppCMS是一个全栈Web框架,其设计目标似乎符合您的需求,请参见http://cppcms.com/wikipp/en/page/when_to_use_cppcms... - SirDarius
它是否支持与Apache Web浏览器(httpd)一起作为模块? - Ritesh Prajapati
虽然CppCMS可以用作自己的Web服务器,但它也可以用于创建FastCGI二进制文件,通过mod_fastcgi或mod_fcgid与Apache Web服务器进行交互。 - SirDarius
你了解 ffead 服务器及其功能吗?它是基于 C++ 的 Restful Web 开发服务,同时支持 JSON 解析器。 - Ritesh Prajapati

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接