diff --git a/compile_commands.json b/compile_commands.json index 1e37a9e..418274b 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -96,13 +96,13 @@ }, { "directory": "/home/adam/github/webcc/build/src/webcc", - "command": "/usr/bin/c++ -DBOOST_ASIO_NO_DEPRECATED -DWEBCC_DEBUG_OUTPUT -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -std=c++11 -o CMakeFiles/webcc.dir/soap_client.cc.o -c /home/adam/github/webcc/src/webcc/soap_client.cc", - "file": "/home/adam/github/webcc/src/webcc/soap_client.cc" + "command": "/usr/bin/c++ -DBOOST_ASIO_NO_DEPRECATED -DWEBCC_DEBUG_OUTPUT -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -std=c++11 -o CMakeFiles/webcc.dir/soap_server.cc.o -c /home/adam/github/webcc/src/webcc/soap_server.cc", + "file": "/home/adam/github/webcc/src/webcc/soap_server.cc" }, { "directory": "/home/adam/github/webcc/build/src/webcc", - "command": "/usr/bin/c++ -DBOOST_ASIO_NO_DEPRECATED -DWEBCC_DEBUG_OUTPUT -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -std=c++11 -o CMakeFiles/webcc.dir/soap_server.cc.o -c /home/adam/github/webcc/src/webcc/soap_server.cc", - "file": "/home/adam/github/webcc/src/webcc/soap_server.cc" + "command": "/usr/bin/c++ -DBOOST_ASIO_NO_DEPRECATED -DWEBCC_DEBUG_OUTPUT -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -std=c++11 -o CMakeFiles/webcc.dir/soap_client.cc.o -c /home/adam/github/webcc/src/webcc/soap_client.cc", + "file": "/home/adam/github/webcc/src/webcc/soap_client.cc" }, { "directory": "/home/adam/github/webcc/build/third_party/jsoncpp", @@ -111,13 +111,13 @@ }, { "directory": "/home/adam/github/webcc/build/example/rest_book_server", - "command": "/usr/bin/c++ -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -I/home/adam/github/webcc/third_party/jsoncpp -std=c++11 -o CMakeFiles/rest_book_server.dir/book_services.cc.o -c /home/adam/github/webcc/example/rest_book_server/book_services.cc", - "file": "/home/adam/github/webcc/example/rest_book_server/book_services.cc" + "command": "/usr/bin/c++ -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -I/home/adam/github/webcc/third_party/jsoncpp -std=c++11 -o CMakeFiles/rest_book_server.dir/main.cc.o -c /home/adam/github/webcc/example/rest_book_server/main.cc", + "file": "/home/adam/github/webcc/example/rest_book_server/main.cc" }, { "directory": "/home/adam/github/webcc/build/example/rest_book_server", - "command": "/usr/bin/c++ -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -I/home/adam/github/webcc/third_party/jsoncpp -std=c++11 -o CMakeFiles/rest_book_server.dir/main.cc.o -c /home/adam/github/webcc/example/rest_book_server/main.cc", - "file": "/home/adam/github/webcc/example/rest_book_server/main.cc" + "command": "/usr/bin/c++ -DWEBCC_ENABLE_SOAP -I/home/adam/include -I/home/adam/github/webcc/src -I/home/adam/github/webcc/third_party -I/home/adam/github/webcc/third_party/jsoncpp -std=c++11 -o CMakeFiles/rest_book_server.dir/book_services.cc.o -c /home/adam/github/webcc/example/rest_book_server/book_services.cc", + "file": "/home/adam/github/webcc/example/rest_book_server/book_services.cc" }, { "directory": "/home/adam/github/webcc/build/example/rest_book_client", diff --git a/example/rest_book_client/main.cc b/example/rest_book_client/main.cc index 24b9132..c87165c 100644 --- a/example/rest_book_client/main.cc +++ b/example/rest_book_client/main.cc @@ -99,30 +99,44 @@ public: return true; } -}; -//////////////////////////////////////////////////////////////////////////////// + bool UpdateBook(const std::string& id, + const std::string& title, + double price) { + Json::Value root(Json::objectValue); + // root["id"] = id; // NOTE: ID is already in the URL. + root["title"] = title; + root["price"] = price; -std::string g_host; -std::string g_port; + Json::StreamWriterBuilder builder; + std::string book_json = Json::writeString(builder, root); -void ListBooks() { - std::cout << "List books" << std::endl; + webcc::HttpResponse http_response; + if (!Request(webcc::kHttpPost, "/books/" + id, book_json, &http_response)) { + return false; + } - BookListClient client(g_host, g_port); + std::cout << http_response.status() << std::endl; - client.ListBooks(); -} + return true; + } -void CreateBook(const std::string& id, - const std::string& title, - double price) { - std::cout << "Create book: " << id << " " << title << " " << price << std::endl; + bool DeleteBook(const std::string& id) { + webcc::HttpResponse http_response; + if (!Request(webcc::kHttpDelete, "/books/" + id, "", &http_response)) { + return false; + } - BookListClient client(g_host, g_port); + std::cout << http_response.content() << std::endl; - client.CreateBook(id, title, price); -} + return true; + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +std::string g_host; +std::string g_port; void Help(const char* argv0) { std::cout << "Usage: " << argv0 << " " << std::endl; @@ -132,16 +146,28 @@ void Help(const char* argv0) { std::string GetUserInput() { char input[256]; - std::size_t length = 0; - do { + // std::size_t length = 0; + // do { std::cout << ">> "; std::cin.getline(input, 256); - length = strlen(input); - } while (length == 0); + // length = strlen(input); + // } while (length == 0); return input; } +bool ParseJsonInput(const std::string& input, Json::Value* root) { + Json::CharReaderBuilder builder; + std::stringstream stream(input); + std::string errs; + if (Json::parseFromStream(builder, stream, root, &errs)) { + return true; + } else { + std::cerr << errs << std::endl; + return false; + } +} + int main(int argc, char* argv[]) { if (argc != 3) { Help(argv[0]); @@ -152,14 +178,16 @@ int main(int argc, char* argv[]) { g_port = argv[2]; // Type commands to execute actions. - // Commands: list, create, update, remove + // Commands: list, create, detail, update, delete and exit. // Examples: // >> list // >> create 1 { "title": "1984", "price": 12.3 } // >> detail 1 - // >> update 1 { "price": 32 } + // >> update 1 { "title": "1Q84", "price": 32.1 } // >> delete 1 + // >> exit + // A very naive implementation of interaction mode. while (true) { std::string input = GetUserInput(); boost::trim(input); @@ -177,7 +205,8 @@ int main(int argc, char* argv[]) { } if (command == "list") { - ListBooks(); + BookListClient client(g_host, g_port); + client.ListBooks(); continue; } @@ -189,21 +218,39 @@ int main(int argc, char* argv[]) { if (command == "create") { std::string json = input.substr(i); - std::cout << "json:" << json << std::endl; Json::Value root; - Json::CharReaderBuilder builder; - std::string errs; - if (Json::parseFromStream(builder, std::stringstream(json), &root, &errs)) { - CreateBook(id, root["title"].asString(), root["price"].asDouble()); - } else { - std::cerr << errs << std::endl; + if (ParseJsonInput(json, &root)) { + BookListClient client(g_host, g_port); + client.CreateBook(id, root["title"].asString(), root["price"].asDouble()); + } + continue; + } + + if (command == "update") { + std::string json = input.substr(i); + + Json::Value root; + if (ParseJsonInput(json, &root)) { + BookDetailClient client(g_host, g_port); + client.UpdateBook(id, root["title"].asString(), root["price"].asDouble()); } + continue; + } + + if (command == "detail") { + BookDetailClient client(g_host, g_port); + client.GetBook(id); + continue; + } + + if (command == "delete") { + BookDetailClient client(g_host, g_port); + client.DeleteBook(id); + continue; } } - //BookDetailClient book_detail_client(host, port); - //book_detail_client.GetBook("1"); return 0; } diff --git a/example/rest_book_server/book_services.cc b/example/rest_book_server/book_services.cc index ac77c51..4c6f6de 100644 --- a/example/rest_book_server/book_services.cc +++ b/example/rest_book_server/book_services.cc @@ -57,6 +57,15 @@ public: return false; } + bool UpdateBook(const Book& book) { + auto it = FindBook(book.id); + if (it != books_.end()) { + it->title = book.title; + it->price = book.price; + } + return false; + } + bool DeleteBook(const std::string& id) { auto it = FindBook(id); @@ -75,6 +84,12 @@ private: [&id](const Book& book) { return book.id == id; }); } + std::list::iterator FindBook(const std::string& id) { + return std::find_if(books_.begin(), + books_.end(), + [&id](Book& book) { return book.id == id; }); + } + private: std::list books_; }; @@ -83,6 +98,23 @@ static BookStore g_book_store; //////////////////////////////////////////////////////////////////////////////// +static bool BookFromJson(const std::string& json, Book* book) { + Json::Value root; + Json::CharReaderBuilder builder; + std::stringstream stream(json); + std::string errs; + if (!Json::parseFromStream(builder, stream, &root, &errs)) { + std::cerr << errs << std::endl; + return false; + } + + book->id = root["id"].asString(); + book->title = root["title"].asString(); + book->price = root["price"].asDouble(); + + return true; +} + bool BookListService::Handle(const std::string& http_method, const std::vector& url_sub_matches, const std::string& request_content, @@ -103,22 +135,11 @@ bool BookListService::Handle(const std::string& http_method, if (http_method == webcc::kHttpPost) { // Add a new book. - - Json::Value root; - Json::CharReaderBuilder builder; - std::stringstream stream(request_content); - std::string errs; - if (!Json::parseFromStream(builder, stream, &root, &errs)) { - std::cerr << errs << std::endl; - return false; - } - Book book; - book.id = root["id"].asString(); - book.title = root["title"].asString(); - book.price = root["price"].asDouble(); - - return g_book_store.AddBook(book); + if (BookFromJson(request_content, &book)) { + return g_book_store.AddBook(book); + } + return false; } return false; @@ -138,20 +159,24 @@ bool BookDetailService::Handle(const std::string& http_method, if (http_method == webcc::kHttpGet) { const Book& book = g_book_store.GetBook(book_id); - - if (book.IsNull()) { - return false; + if (!book.IsNull()) { + Json::StreamWriterBuilder builder; + *response_content = Json::writeString(builder, book.ToJson()); + return true; } - - Json::StreamWriterBuilder builder; - *response_content = Json::writeString(builder, book.ToJson()); - - return true; + return false; } else if (http_method == webcc::kHttpPost) { + // Update a book. + Book book; + if (BookFromJson(request_content, &book)) { + book.id = book_id; + return g_book_store.UpdateBook(book); + } + return false; } else if (http_method == webcc::kHttpDelete) { - + return g_book_store.DeleteBook(book_id); } return false;