Web application framework for c++. Non blocking sockets, http, websocket protocols supported. Postgresql connector for now. Multithreading app support
Elvis intends to be a c++ web framework.
Inside elvis folder are the library source files and headers.
Inside samples folder there is an example application.
CMAKE support has been added. Two third party libraries are used,
libpqxx version 5.0.1 and cryptopp version 5.6.2
./samples/example_app/server hostname port threads
Create and access elvis from everywhere.
#include <elvis/app_context.h>
app* elvis = Elvis::App::GetInstance();
Use framework cache to cache data:
std::string key;
std::string data;
elvis->Cache(key, data);
Use framework cache to retrieve data:
std::string key;
std::string data = elvis->GetCacheData(key);
Use framework JSON deserializer:
std::string serializedData;
std::list<std::unordered_map<std::string, std::string>> json = elvis->JSONDeserialize(std::move(serializedData));
Use framework DB engine to create and retrieve models based on string query.
std::string query;
elvis->CreateModel(query);
elvis->RetrieveModel(query);
std::unique_ptr<Elvis::RouteManager> routeManager = std::make_unique<Elvis::RouteManager>();
routeManager->SetRoute("/file", "GET", std::move(std::make_unique<FileGetController>()));
routeManager->SetRoute("/file", "POST", std::move(std::make_unique<FilePostController>()));
Configure app with hostname, port, thread number, routes logfile and loglevel.
elvis->Configure(ipaddr, port, thread_number, routeManager, "server.log", Elvis::LogLevel::INFO);
Default configure provides
Run threaded applications. The call below will block.
elvis->Run();
// Override IModel
class FileModel final: IModel {
private:
std::unique_ptr<Attribute<std::string>> m_Filename;
std::unique_ptr<Attribute<std::string>> m_Md5;
public:
FileModel() = delete;
explicit FileModel(std::string filename, std::string md5);
virtual void Create() const override;
virtual void Retrieve() const override;
virtual void Display() const override;
};
void FileModel::Create() const
{
std::string sql = "insert into operations (filename, md5) values ('test.txt', '1234')";
auto elvis = App::GetInstance();
elvis->CreateModel(sql);
}
// Override Elvis::IController
class FilePostController final: public Elvis::IController
{
public:
explicit FilePostController();
void DoStuff(std::unordered_map<std::string, std::string> &deserialized_input_data) override;
};
void FilePostController::DoStuff(std::unordered_map<std::string, std::string> &deserialized_input_data)
{
// This is json data so further deserialization is needed. The result is a list of objects.
// Here we expect only one.
auto elvis = App::GetInstance();
auto input = elvis->JSONDeserialize(std::move(deserialized_input_data["data"])).front();
if (input.empty())
{
std::cout << "FilePostController: 400 Bad Request\n";
deserialized_input_data["status"] = "400 Bad Request";
return;
}
auto file_model = std::make_unique<FileModel>(input["filename"], input["md5sum"]);
file_model->Create();
elvis->Cache(input["filename"], read_from_file("", input["filename"]));
}
// Register the controller.
std::unique_ptr<Elvis::RouteManager> routeManager = std::make_unique<Elvis::RouteManager>();
routeManager->SetRoute("/file", "POST", std::move(std::make_unique<FilePostController>()));