-
Notifications
You must be signed in to change notification settings - Fork 2
Home
cervpp project is developed to be a plain C++ http-server. There are different types of http server projects written in C++ but I found out that they are hard to use compared to other languages, e.g Javascript with Node.js. So I wanted to develop an http server with C++ so that it'll be faster than scripting languages, easy to use along the way (not as much as it is with Javascript maybe, but still usable), and wanted to teach myself some stuff along the way.
This project is developed with C++17 and similar API to Node.js express.js environment.
The main class of this project is HttpServer (again, as expected). The user only needs to create an HttpServer object, and ready to go.
#include "HttpServer.h"
HttpServer server;
Only thing to consider is it requires some configuration. For which I created a Configuration singleton class (I know, it is bad to use singleton) to pass parsed configuration throughout the classes, and you may need to pass a json config file to it before initializing HttpServer.
std::ifstream ifs("/path/to/config/httpserver.json");
Configuration::parseFile(ifs);
HttpServer server;
So now, you need to create endpoints. To make it similar to Node.js and express.js, you just need to create a controller object and give route to it.
#include "RestfulAPIController.h"
auto restController = std::make_shared<RestfulAPIController>();
restController->route(GET, "/", [] (std::shared_ptr<HttpRequest> req, std::shared_ptr<HttpResponse> res) {
res->sendJson(R"({"status": "OK"})");
});
// this is easier to write but IDEs doesn't support code completion with auto arguments
restController->route(POST, "/", [] (auto req, auto res) {
res->sendJson(req->getJsonBody());
});
There are three predefined controllers: StaticFileController
, ResourceController
, and RestfulAPIController
.
StaticFileController
is just a static file server controller, serving the file in request path. For example, if request is sent to localhost/example/index.html
, then this controller looks for example/index.html
file and serves it if found.
ResourceController
is not working in this version. Just skipping it.
This controller serves REST APIs. You can give method and path to serve, and do your thing in the callback function. In addition, you can give middlewares to it just as express.js. More examples coming.
As expected, some parts of cervpp project are reusable accross projects, so I added them to brutils library. I know I said this project is plain C++ but it is, just with a utility library brutils. I'll make some changes so that brutils is part of this project, so anybody can clone and start working. Just didn't do it, yet.
I developed a brutils::variant class that is very similar to QVariant of Qt project, and used std::any for easy implementation. Added brutils::variant_map (which is an alias for std::map<std::string, brutils::variant>) and brutils::variant_list (which is an alias for std::vectorbrutils::variant). These types added for easy usage of complex data structures, as json.
There are brutils::json_parser and brutils::json_generator classes, as expected, used to parse and generate json data. Parser takes string and returns brutils::variant, generator takes brutils::variant and returns string. With brutils::variant, the json content made easy to alter with.