2019/08/14:這篇文章已通過時了。Webcc 已經演化成了一個比較完備的純 HTTP 程序庫。
詳見:Webcc: 輕量級 C++ HTTP 程序庫git
Webcc 是我本身寫的一個 C++ Web Service 程序庫,網絡通訊基於 Boost Asio,跨平臺,輕量、高效。它並不是只是一個玩具,目前正應用於咱們實際的項目,並且還在不斷更新和完善。github
Webcc 同時支持客戶端和服務端,你能夠用它調用已經存在的 Web Service,也能夠用它實現本身的 Web Service,且同時支持 REST 和 SOAP 兩種方式。web
考慮到用 SOAP 的人愈來愈少,webcc 對 SOAP 的支持能夠經過宏 WEBCC_ENABLE_SOAP
在編譯時徹底剔除掉。正則表達式
Webcc 內部對 SOAP 消息的包裝和解析依賴於 PugiXml。若是禁掉 SOAP,PugiXml 天然也會一併禁掉;若是啓用 SOAP,但願你能承擔對 PugiXml 的這一份小小依賴。數據庫
對 SOAP 部分的介紹就這麼多,具體可見去年的這篇文章:C++ 調用 SOAP Web Service。segmentfault
假定你要提供一個關於圖書的 REST Server,提供下面這些操做或接口:網絡
前面兩個操做能夠經過繼承 webcc::RestListService
來實現:框架
class BookListService : public webcc::RestListService { protected: // 查詢圖書(基於某些特定的條件) // GET /books?<query> bool Get(const webcc::UrlQuery& query, std::string* response_content) override; // 添加一本新圖書 // POST /books // |request_content| 包含了新圖書的數據,爲 JSON 格式的字符串 bool Post(const std::string& request_content, std::string* response_content) override; };
其餘幾個操做,則須要繼承自 webcc::RestDetailService
:ide
class BookDetailService : public webcc::RestDetailService { protected: // 獲取一本圖書的詳細信息 bool Get(const std::vector<std::string>& url_sub_matches, const webcc::UrlQuery& query, std::string* response_content) override; // 更新一本圖書的信息 bool Put(const std::vector<std::string>& url_sub_matches, const std::string& request_content, std::string* response_content) override; // 刪除一本圖書 bool Delete(const std::vector<std::string>& url_sub_matches) override; };
在 Python 的 Django 框架中,有幾種不一樣的視圖(View),其中 XxxListView
對應於一列對象,而 XxxDetailView
對應於單個對象。Webcc 的 RestListService
和 RestDetailService
就是參考了 Django 的這一設計。url
對於 RestListService
,URL 通常爲複數形式,好比 /books
。對於 GET 請求,就是查詢對象,URL 通常會帶 query,好比 /books?author=Barnes
;對於 POST 請求,就是建立新對象,信息由 HTTP 請求體攜帶,通常爲 JSON 格式。
對於 RestDetailService
,URL 通常爲單數,好比 /book
,而後還要指定對象的 ID,最終的 URL 格式爲 /book/{BookID}
,這個 ID 最終能夠經過 url_sub_matches
這個參數拿到。RestDetailService
支持 GET、PUT、PATCH 和 DELETE 幾種請求,分別對應於獲取、更新、部分更新和刪除。
下面看一下 BookDetailService::Get()
的實現:
bool BookDetailService::Get(const std::vector<std::string>& url_sub_matches, const webcc::UrlQuery& query, std::string* response_content) { if (url_sub_matches.size() != 1) { return false; } const std::string& book_id = url_sub_matches[0]; // 接下來: // - 經過 book_id 從數據庫拿到這個圖書, // - 而後把圖書信息轉換成 JSON 格式的字符串, // - 最後把 JSON 字符串賦值給輸出參數 response_content。 }
Service 本身並不能運行,須要把它們綁定到 RestServer
,下面是 main()
裏的部分代碼:
webcc::RestServer server(8080, 2); server.Bind(std::make_shared<BookListService>(), "/books", false); server.Bind(std::make_shared<BookDetailService>(), "/book/(\\d+)", true); server.Run();
先建立一個 RestServer
對象,端口號爲 8080
,後臺的工做線程數爲 2
。
而後分別建立 BookListService
和 BookDetailService
,都用 std::shared_ptr
來自動管理對象生命期。
最後綁定 services 到特定的 URL,其中 BookDetailService
的 URL 是一個正則表達式,(\\d+)
最後匹配下來的部分就存在參數 url_sub_matches
中。