#include #include "json/json.h" #include "webcc/logger.h" #include "webcc/rest_async_client.h" #include "example/common/book.h" #include "example/common/book_json.h" // ----------------------------------------------------------------------------- class BookClientBase { public: BookClientBase(boost::asio::io_context& io_context, const std::string& host, const std::string& port, int timeout_seconds) : rest_client_(io_context, host, port) { rest_client_.SetTimeout(timeout_seconds); } virtual ~BookClientBase() = default; protected: void PrintSeparateLine() { std::cout << "--------------------------------"; std::cout << "--------------------------------"; std::cout << std::endl; } // Generic response handler for RestAsyncClient APIs. void GenericHandler(std::function rsp_callback, webcc::HttpResponsePtr response, webcc::Error error, bool timed_out) { if (error != webcc::kNoError) { std::cout << webcc::DescribeError(error); if (timed_out) { std::cout << " (timed out)"; } std::cout << std::endl; } else { // Call the response callback on success. rsp_callback(response); } } webcc::RestAsyncClient rest_client_; }; // ----------------------------------------------------------------------------- class BookListClient : public BookClientBase { public: BookListClient(boost::asio::io_context& io_context, const std::string& host, const std::string& port, int timeout_seconds) : BookClientBase(io_context, host, port, timeout_seconds) { } void ListBooks(webcc::HttpResponseCallback callback) { std::cout << "ListBooks" << std::endl; rest_client_.Get("/books", callback); } void CreateBook(const std::string& title, double price, std::function id_callback) { std::cout << "CreateBook: " << title << " " << price << std::endl; Json::Value json(Json::objectValue); json["title"] = title; json["price"] = price; auto rsp_callback = [id_callback](webcc::HttpResponsePtr response) { Json::Value rsp_json = StringToJson(response->content()); id_callback(rsp_json["id"].asString()); }; rest_client_.Post("/books", JsonToString(json), std::bind(&BookListClient::GenericHandler, this, rsp_callback, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } }; // ----------------------------------------------------------------------------- class BookDetailClient : public BookClientBase { public: BookDetailClient(boost::asio::io_context& io_context, const std::string& host, const std::string& port, int timeout_seconds) : BookClientBase(io_context, host, port, timeout_seconds) { } void GetBook(const std::string& id, webcc::HttpResponseCallback callback) { std::cout << "GetBook: " << id << std::endl; auto rsp_callback = [](webcc::HttpResponsePtr response) { Json::Value rsp_json = StringToJson(response->content()); //id_callback(rsp_json["id"].asString()); }; rest_client_.Get("/books/" + id, callback); } void UpdateBook(const std::string& id, const std::string& title, double price, webcc::HttpResponseCallback callback) { std::cout << "UpdateBook: " << id << " " << title << " " << price << std::endl; // NOTE: ID is already in the URL. Json::Value json(Json::objectValue); json["title"] = title; json["price"] = price; rest_client_.Put("/books/" + id, JsonToString(json), callback); } void DeleteBook(const std::string& id, webcc::HttpResponseCallback callback) { std::cout << "DeleteBook: " << id << std::endl; rest_client_.Delete("/books/" + id, callback); } }; // ----------------------------------------------------------------------------- void Help(const char* argv0) { std::cout << "Usage: " << argv0 << " [timeout]" << std::endl; std::cout << " E.g.," << std::endl; std::cout << " " << argv0 << " localhost 8080" << std::endl; std::cout << " " << argv0 << " localhost 8080 2" << std::endl; } int main(int argc, char* argv[]) { if (argc < 3) { Help(argv[0]); return 1; } WEBCC_LOG_INIT("", webcc::LOG_CONSOLE); std::string host = argv[1]; std::string port = argv[2]; int timeout_seconds = -1; if (argc > 3) { timeout_seconds = std::atoi(argv[3]); } boost::asio::io_context io_context; BookListClient list_client(io_context, host, port, timeout_seconds); BookDetailClient detail_client(io_context, host, port, timeout_seconds); // Response handler. auto handler = [](webcc::HttpResponsePtr response, webcc::Error error, bool timed_out) { if (error == webcc::kNoError) { std::cout << response->content() << std::endl; } else { std::cout << webcc::DescribeError(error); if (timed_out) { std::cout << " (timed out)"; } std::cout << std::endl; } }; list_client.ListBooks(handler); list_client.CreateBook("1984", 12.3, [](std::string id) { std::cout << "ID: " << id << std::endl; }); //detail_client.GetBook("1", handler); //detail_client.UpdateBook("1", "1Q84", 32.1, handler); //detail_client.GetBook("1", handler); //detail_client.DeleteBook("1", handler); //list_client.ListBooks(handler); io_context.run(); return 0; }