Разбор REST-запроса в C ++ - PullRequest
       38

Разбор REST-запроса в C ++

5 голосов
/ 05 февраля 2012

Я хотел бы предоставить REST API для моего приложения, используя веб-сервер Mongoose и предоставляя обработчики для различных запросов.

Пример запроса может быть таким (на данный момент я использую только 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: Я хочу иметь возможность обрабатывать REST-запросы в C ++ с чем-то вроде этого:

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

Возможно ли это?

Ответы [ 3 ]

4 голосов
/ 05 февраля 2012

Довольно несексуальным, но простым подходом было бы просто использовать sscanf. Простите за довольно C-подобный код. Обратите внимание, что это не обеспечивает тот синтаксис, который вы ищете, но не требует никаких библиотек, расширений или улучшений.

Например,

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
}
1 голос
/ 20 февраля 2012

В процессе поиска кода Python я обнаружил, что веб-фреймворк Flask имеет особый способ синтаксического анализа путей REST :

Вы объявляете путь, подобный этому:

@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 ++.
Я получу ответ Тома, поскольку он уместен, и я думаю, что моя реализация будет выглядеть примерно так, как он предлагает (хотя я предпочитаю iostreams).

Я оставлю этот ответ здесь, чтобыкто-нибудь прячется.

0 голосов
/ 07 июня 2018

Проект drogon на github ( project Drogon, веб-фреймворк c ++ 11 ) может быть полезен для вас.В этой среде вы можете зарегистрировать свой метод-обработчик следующим образом:

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

метод может быть любым вызываемым объектом class Класс HttpApiController - это простой класс-оболочка, который позволяет вам регистрировать функции с помощью макросов.В проекте есть примеры, демонстрирующие использование этих функций:

Надеюсь, это поможет вам ..

...