【问题标题】:Parse REST query in C++在 C++ 中解析 REST 查询
【发布时间】:2012-02-05 10:58:12
【问题描述】:

我想在我的应用程序上公开一个 REST API,使用 Mongoose Web 服务器并为不同的查询提供处理程序。

查询的一个例子是这样的(我现在只使用 GET,其余的 HTTP 动词稍后会出现):

GET /items -> returns a list of all items in JSON
GET /item/by/handle/123456789 -> returns item that has handle 123456789
GET /item/by/name/My%20Item -> returns item(s) that have the name "My Item"

我很好奇应该如何实现这些查询的解析。我可以轻松解析第一个,因为这只是if( query.getURI() == "/items") return ... 的问题。
但是对于接下来的两个查询,我必须以完全不同的方式操作 std:: 字符串,使用一些 std::string::find() 魔法和偏移量来获取参数。

例如,这是我对第二个查询的实现:

size_t position = std::string::npos;
std::string path = "/item/by/handle/";

if( (position = query.getURI().find(path) ) != std::string::npos )
{
    std::string argument = query.getURI().substr( position + path.size() );
    // now parse the argument to an integer, find the item and return it
}

如果我想“模板化”这个怎么办?含义:我描述了路径和之后我期望的参数(一个整数,一个字符串,....);并且自动生成代码来处理这个?

Tl;Dr:我希望能够在 C++ 中处理 REST 查询,其中包含以下内容:

registerHandler( "/item/by/handle/[INTEGER]", myHandlerMethod( int ));

这可能吗?

【问题讨论】:

  • 听起来你需要正则表达式,就像在 boost 或 C++11 中找到的那样。

标签: c++ rest parsing mongoose-web-server


【解决方案1】:

一个相当不性感但简单的方法是简单地使用 sscanf。请原谅类似 C 的代码。请注意,这不提供您正在寻找的那种语法,但它不需要任何库、扩展或 boost。

例如,

int param; int a, b; char c[255]; /* recall that sscanf returns the number of variables filled */ if( 1 == sscanf( query.getURI(), "/item/by/handle/%d", &param ) ) { handler( param ); } else if ( 3 == sscanf( query.getURI(), "/more/params/%d/%d/%s", &a, &b, &c ) ) { anotherHandler( a, b, c ); } else { // 404 }

【讨论】:

  • 请注意,使用 %s 对用户输入是危险的,因为它不检查边界并且很容易溢出。我建议上面的例子:sscanf(query.getURI(), "/more/params/%d/%d/%254s", &a, &b, c)
  • 好点。对于那些想要阻止这种情况的人,Kernighan 和 Pike 有一个简单的解决方案:stackoverflow.com/questions/1621394/…
【解决方案2】:

github上的项目drogon(project Drogon,a c++11 web framework)可能对你有帮助。在这个框架中,您可以像这样注册您的处理程序方法:

drogon::HttpAppFramework::registerHttpApiMethod("/api/v1/handle/{1}/{2}",yourMethod...);

yourMethod 可能是任何可调用对象。

HttpApiController 类是一个简单的包装类,允许您使用宏注册函数。项目中有示例演示了这些功能的使用。

希望对你有帮助..

【讨论】:

    【解决方案3】:

    在搜索一些 Python 代码时,我发现 Flask Web 框架有一个 particular way of parsing REST paths

    你声明一个这样的路径:

    @app.route('/post/<int:post_id>')
    def show_post(post_id):
        # show the post with the given id, the id is an integer
        return 'Post %d' % post_id
    

    Flask 会构建所需的内容,为您提供所需的整数。

    这正是我需要的,所以我想我必须自己用 C++ 来做。
    我会得到 Tom 的答案,因为它是相关的,我想我的实现看起来有点像他建议的(虽然我更喜欢 iostreams)。

    我会把这个答案留给任何潜伏的人。

    【讨论】:

    • 您最终是否在 C++ 中实现了这种语法? - 如果是这样,您是否考虑过开源它? :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 2019-05-03
    相关资源
    最近更新 更多