2017-01-11 11 views
1

나는 casablanca를 사용하여 간단한 JSON 서버를 구현하는이 코드를보고있다. 나는 지금까지 더 좋은 예를 찾지 못했습니다. 저자는 각 API에 대해 다른 HTTP 메소드를 사용하는 것으로 보입니다. 이는 서버가 많은 API를 사용하게 될 때 문제가 될 수 있습니다. 이 문제를 어떻게 해결해야합니까? 다중 http_listeners가 필요하다는 뜻인가요?casablanca에서 다중 API 구현하기

#include <cpprest/http_listener.h> 
#include <cpprest/json.h> 

using namespace web; 
using namespace web::http; 
using namespace web::http::experimental::listener; 

#include <iostream> 
#include <map> 
#include <set> 
#include <string> 
using namespace std; 

#define TRACE(msg)   wcout << msg 
#define TRACE_ACTION(a, k, v) wcout << a << L" (" << k << L", " << v << L")\n" 

map<utility::string_t, utility::string_t> dictionary; 
typedef std::vector<std::pair<utility::string_t, json::value>> field_map; 
/* handlers implementation */ 

void handle_get(http_request request) 
{ 
    TRACE(L"\nhandle GET\n"); 

    field_map answer; 

    for (auto const & p : dictionary) 
    { 
     answer.push_back(make_pair(p.first, json::value(p.second))); 
    } 

    request.reply(status_codes::OK, json::value::object(answer)); 
} 

void handle_request(http_request request, 
    function<void(json::value &, field_map &)> action) 
{ 
    field_map answer; 

    request 
     .extract_json() 
     .then([&answer, &action](pplx::task<json::value> task) { 
     try 
     { 
      auto & jvalue = task.get(); 

      if (!jvalue.is_null()) 
      { 
       action(jvalue, answer); 
      } 
     } 
     catch (http_exception const & e) 
     { 
      wcout << e.what() << endl; 
     } 
    }) 
     .wait(); 

    request.reply(status_codes::OK, json::value::object(answer)); 
} 

void handle_post(http_request request) 
{ 
    TRACE("\nhandle POST\n"); 

    handle_request(
     request, 
     [](json::value & jvalue, field_map & answer) 
    { 
     for (auto const & e : jvalue.as_array()) 
     { 
      if (e.is_string()) 
      { 
       auto key = e.as_string(); 

       auto pos = dictionary.find(key); 
       if (pos == dictionary.end()) 
       { 
        answer.push_back(make_pair(key, json::value(L"<nil>"))); 
       } 
       else 
       { 
        answer.push_back(make_pair(pos->first, json::value(pos->second))); 
       } 
      } 
     } 
    } 
    ); 
} 

void handle_put(http_request request) 
{ 
    TRACE("\nhandle PUT\n"); 

    handle_request(
     request, 
     [](json::value & jvalue, field_map & answer) 
    { 
     for (auto const & e : jvalue.as_object()) 
     { 
      if (e.second.is_string()) 
      { 
       auto key = e.first; 
       auto value = e.second.as_string(); 

       if (dictionary.find(key) == dictionary.end()) 
       { 
        TRACE_ACTION(L"added", key, value); 
        answer.push_back(make_pair(key, json::value(L"<put>"))); 
       } 
       else 
       { 
        TRACE_ACTION(L"updated", key, value); 
        answer.push_back(make_pair(key, json::value(L"<updated>"))); 
       } 

       dictionary[key] = value; 
      } 
     } 
    } 
    ); 
} 

void handle_del(http_request request) 
{ 
    TRACE("\nhandle DEL\n"); 

    handle_request(
     request, 
     [](json::value & jvalue, field_map & answer) 
    { 
     set<utility::string_t> keys; 
     for (auto const & e : jvalue.as_array()) 
     { 
      if (e.is_string()) 
      { 
       auto key = e.as_string(); 

       auto pos = dictionary.find(key); 
       if (pos == dictionary.end()) 
       { 
        answer.push_back(make_pair(key, json::value(L"<failed>"))); 
       } 
       else 
       { 
        TRACE_ACTION(L"deleted", pos->first, pos->second); 
        answer.push_back(make_pair(key, json::value(L"<deleted>"))); 
        keys.insert(key); 
       } 
      } 
     } 

     for (auto const & key : keys) 
      dictionary.erase(key); 
    } 
    ); 
} 

int main() 
{ 
    http_listener listener(L"http://localhost/restdemo"); 

    listener.support(methods::GET, handle_get); 
    listener.support(methods::POST, handle_post); 
    listener.support(methods::PUT, handle_put); 
    listener.support(methods::DEL, handle_del); 

    try 
    { 
     listener 
      .open() 
      .then([&listener]() {TRACE(L"\nstarting to listen\n"); }) 
      .wait(); 

     while (true); 
    } 
    catch (exception const & e) 
    { 
     wcout << e.what() << endl; 
    } 

    return 0; 
} 

답변

1

예, URI를 기반으로 여러 개의 http_listeners를 가질 수 있습니다. 잘 작동합니다.

+0

감사합니다. 시도해 보겠습니다. – asla