cinatra是什么?
cinatra是C++開源社區–purecpp發起的一個開源項目,現在正式發布第一個版本cinatra0.9.0,cinatra是一個現代C++寫的web framework,它的目的是給用戶提供一個易用、靈活和高性能的web框架,讓用戶能完全專注於核心邏輯而無需關注http細節。它的靈感來源於sinatra,但又有自己的特色。
如何使用
1.從github上下載源碼。
2.安裝boost,因為框架用到asio和coroutine,需要1.57及以上的版本。
3.編譯。已經提供vs2013的工程文件和Cmakelist,直接在win和linux平台下編譯即可。
示例
#include <cinatra/cinatra.hpp> using namespace cinatra; int main() { SimpleApp app; app.route("/", [](Request& req , Response& res) { res.end("Hello Cinatra"); }); app.listen("http").run(); return 0; }
運行起來之后,在瀏覽器中輸入:127.0.0.1就可以看到返回的” Hello Cinatra”, 用起來是不是很簡單,cinatra框架幫你把很多事情都做好了,你只需要關注你的核心業務邏輯即可。讓我們繼續看一個稍微復雜一點的例子。
#include <cinatra/cinatra.hpp> using namespace cinatra; int main() { SimpleApp app; app.route("/hello", [](Request& req , Response& res) { res.end("Hello " + req.query().get_val("name")); }); app.route("/hello/:name/:age", [](Request& req, Response& res, const std::string& a, int b) { res.end("Name: " + a + " Age: " + boost::lexical_cast<std::string>(b)); }); app.listen("http").run(); return 0; }
瀏覽器中輸入:127.0.0.1/hello?name=test&age=12,頁面將輸出” Hello test”。 為了讓用戶用起來更方便,我們還支持下面這種url請求方式:127.0.0.1/hello/test/12,這個url將會被路由到”/hello/:name/:age”對應的handler:[](Request& req, Response& res, const std::string& a, int b);
Router不僅僅支持lambda表達式還支持類的成員函數,如果你想把handler放到類對象中,你可以這樣做。
struct MyStruct { void hello(Request& req, Response& res) { res.end("Hello " + req.session().get<std::string>("uid") + "!"); } }; MyStruct t; // 訪問/hello app.route("/hello", &MyStruct::hello, &t);
cinatra不僅僅使用簡單,還很靈活,它支持AOP,我們可以很方便的將非核心邏輯和核心邏輯分離,比如下面的例子。
struct CheckLoginAspect { void before(Request& req, Response& res) { //如果session沒有uid且訪問的不是login和test_post頁面 if (!req.session().exists("uid")&&req.path()!="/login.html"&& req.path() != "/test_post"&&req.path().compare(0, 7, "/public")) { // 跳轉到登陸頁面 res.redirect("/login.html"); } } void after(Request& req , Response& res) { } }; #include <cinatra/cinatra.hpp> using namespace cinatra; int main() { Cinatra<CheckLoginAspect> app; app.route("/", [](Request& req , Response& res) { res.end("Hello Cinatra"); }); app.listen("http").run(); return 0; }
上面的例子中我們增加了一個檢查是否登錄的切面,如果用戶沒登錄將會重定向到登錄頁面。我們還可以自由組合多個切面,cinatra可以很方便地擴展任意多個切面。你可以這樣擴展切面。
struct CheckLoginAspect { void before(Request& req, Response& res) { //如果session沒有uid且訪問的不是login和test_post頁面 if (!req.session().exists("uid")&&req.path()!="/login.html"&& req.path() != "/test_post"&&req.path().compare(0, 7, "/public")) { // 跳轉到登陸頁面 res.redirect("/login.html"); } } void after(Request& req , Response& res) { } }; struct LogAspect { void before(cinatra::Request& req, cinatra::Response& res) { std::cout << "log before" << std::endl; } void after(cinatra::Request& /* req */, cinatra::Response& /* res */) { std::cout << "log after" << std::endl; } }; #include <cinatra/cinatra.hpp> using namespace cinatra; int main() { Cinatra<CheckLoginAspect, LogAspect> app; //擴展了一個記錄日志的切面 app.route("/", [](Request& req , Response& res) { res.end("Hello Cinatra"); }); app.listen("http").run(); return 0; }
性能
用ab工具和另外一個c++ web框架crow做了一下性能對比:
crow:
cinatra:
可以看到cinatra比crow的性能略高。現在第一個版本還沒有專門去做優化,主要是完成了基本功能,后續會持續優化的,也歡迎大家幫忙做進一步的性能測試。
cinatra的設計
cinatra的設計非常簡單,只有幾個組件,下面是cinatra的邏輯視圖。
用戶僅用cinatra即可,其它的事情框架已經幫用戶做好了,用戶只用關注核心邏輯即可,這些核心邏輯都在handler中處理,而這些handler完全由用戶自定義和擴展。
roadmap
目前支持了http1.0和1.1,支持了session和cookie,后續計划:
- https
- html模板
- websocket
- cinatra打造purecpp社區
開發和參與者
C++開源社區:http://purecpp.org/,qicosmos(江南),網事如風,SIGSEGV,海盜,福爾摩斯喵。
如果你發現了問題請及時到社區反饋給我們,也歡迎提出寶貴意見。希望更多的人能參與進來。
如果你覺得cinatra不錯,請不要吝惜給一個star^_^。