Skip to content
This repository has been archived by the owner on Nov 15, 2019. It is now read-only.

Introduction

VOID_133 edited this page Aug 8, 2015 · 6 revisions

Welcome to the cinatra wiki! cinatra–a sinatra inspired modern c++ web framework

What is cinatra?

Cinatra is a opensource project created by Purecpp community, Now we release the first version cinatra0.9.0. Cinatra is a modern web framework written in modern C++, aiming at providing developer with a stable easy-to-use,flexible and high-performance web framework . Cinatra can make developers fully focus on the core logic of their code regardless of the details of http. Cinatra is inspired by sinatra , and it's different from it.

How to use it

  • Download the code from github git clone https://github.com/topcpporg/cinatra.git
  • Install boost library,Cinatra uses asio and coroutine both needed 1.57 or higher version
  • Compile it! Both Cmakelist and Visual Studio 2013 Project file is given, you can directly compile it from source on either Linux or Windows platform

Samples

#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;
}

When the code is running , just type 127.0.0.1 in your browser , you will see "Hello Cinatra" on it. Isn't it easy to use? Cintra has helped you with lots of things, you just need to focus on the core logic, let's go on and see a more tricky example.

#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;
}

Type 127.0.0.1/hello?name=test&age=12 in your browser , You will see "Hello test" on the page

**P.S.**For users' convenience ,We also support the following request method:127.0.0.1/hello/test/12,this URL will be route to the handler correspond to '/hello/:name/:age' [](Request& req, Response& res, const std::string& a, int b);

Router not only supports lambda expressions but also support member functions of a certain class. If you want to put handler into an object you can just follow these instructions below

struct MyStruct
{
	void hello(Request& req, Response& res)
	{
		res.end("Hello " + req.session().get<std::string>("uid") + "!");
	}
};
MyStruct t;
// Visit/hello
app.route("/hello", &MyStruct::hello, &t);

Cinatra is both easy-to-use and flexible, and it supports AOP , users can easily deal with core logic and non-core logic separately . See the following example.

    struct CheckLoginAspect
    {
    	void before(Request& req, Response& res)
    	{
                //If uid doesn't exist in seesion and not visiting login or test_post page
    		if (!req.session().exists("uid")&&req.path()!="/login.html"&&
    			req.path() != "/test_post"&&req.path().compare(0, 7, "/public"))
     		{
     			// navigate to login page
     			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;
    }

We add a check-login section in the previous example,if user doesn't login, he will be redirect to login page. We can also combine multiple sections as you like, Cintra is easy to develop with arbitrary numbers of sections. For example , you can set your sections like this

struct CheckLoginAspect
{
	void before(Request& req, Response& res)
	{
		//No session uid and not requiring /login.html
		if (!req.session().exists("uid")&&req.path()!="/login.html"&&
			req.path() != "/test_post"&&req.path().compare(0, 7, "/public"))
 		{
 			// Redirect to login page
 			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; //expand a logging section
	app.route("/", [](Request&  req , Response& res)
	{
		res.end("Hello Cinatra");
	});
 
	app.listen("http").run();
 
	return 0;
}

Performance

use ab to compare the Cintra with another web Framework Crow: crow:

cinatra:

As the result, Cintra perform a little better than crow, and our first release version is not well-optimized yet. Later we'll optimize it and get a better performance.Also,you are welcomed to do some tests for us~!

The Design of Cinatra

Cinatra only contains a few modules,Below is the UML view of Cinatra

Users only need to use cinatra module, other complicated things are done by the framework automatically,you just need to focus on the core logic,which is processed in handler. And Handler is easy to customize and expand

roadmap

Now supports http1.0 and http1.1, session and cookie are supported

TODO list

  1. https
  2. html template
  3. websocket
  4. Power purecpp with cinatra

C++Open Source Commuinty http://purecpp.org/

For more details and samples on Cinatra , Please refer to github

For bugs issue, please report them in our community.And please give us advice to improve Cinatra. And Welcome your participate!

If you like cinatra . Please star it ^_^

Clone this wiki locally