IncludeOS C++ Web Application Framework
Acorn is a web server built with Mana which demonstrates a lot of its potential.
Some insight in the implementation of mana can be found in this post.
It's easy to get started - check out the examples.
using namespace mana; using namespace std::string_literals; std::unique_ptr<Server> server; void Service::start(const std::string&) { Router router; // GET / router.on_get("/", [](auto, auto res) { res->add_body("<html><body><h1>Simple example</h1></body></html>"s); res->send(); }); server = std::make_unique<Server>(net::Inet4::stack()); server->set_routes(router).listen(80); }Routes is where the server end-points are defined.
Router router; // GET / router.on_get("/", [] (auto req, auto res) { // Serve index.html }); // POST /users router.on_post("/users", [] (auto req, auto res) { // Register new user }); server.set_routes(router);There is also support for named parameters in routes.
// GET /users/:id router.on_get("/users/:id(\\d+)", [](auto req, auto res) { auto id = req->params().get("id"); // Do actions according to "id" if(id == "42") // ... });Middleware are tasks which are executed before the user code defined in routes.
// Declare a new middleware class MyMiddleware : public mana::Middleware { // ... }; // Add a middleware object Middleware_ptr my_mw = std::make_shared<MyMiddleware>(); server.use(my_mw);It's also possible to just add a simple task with a lambda.
// Add a middleware lambda server.use([] (auto req, auto res) { // My custom middleware function (*next)(); // Don't forget to call next if no response was sent! });Psst, there is already some ready-made middleware for Mana!
Attributes is a way to extend the Request object with additional data.
// Declare a new attribute class MyAttribute : public Attribute { // ... }; // Set attribute in middleware MyMiddleware::process(auto req, auto res, auto next) { auto attr = std::make_shared<MyAttribute>(); req->set_attribute(attr); (*next)(); } // Use attribute in route router.use("/my-route", [] (auto req, auto res) { if(auto attr = req->get_attribute<MyAttribute>()) { // Do things with "attr" } });