C++ backend URL Routing

currently im writing this web app with my backend being in c++ basically after parsing the http request string I just have a bunch of conditional statements calling relevant "controllers" to handle actions for example
c++
...
else if(req.URI == "/logout") {
handle_logout(req, client_socket);
}

else if (req.URI.find("/search") == 0) {
std::unordered_map<std::string, std::string> params = parse_parameters(req.URI);
if (params.find("query") != params.end())
handle_search(req, client_socket, params["query"]);
else
sendNotFoundResponse(client_socket);
}
...etc
c++
...
else if(req.URI == "/logout") {
handle_logout(req, client_socket);
}

else if (req.URI.find("/search") == 0) {
std::unordered_map<std::string, std::string> params = parse_parameters(req.URI);
if (params.find("query") != params.end())
handle_search(req, client_socket, params["query"]);
else
sendNotFoundResponse(client_socket);
}
...etc
with controllers which are defined like bellow with some logic
c++
void handle_logout(HTTPRequest& req, int client_socket);
void handle_search(HTTPRequest& req, int client_socket, std::string query);
c++
void handle_logout(HTTPRequest& req, int client_socket);
void handle_search(HTTPRequest& req, int client_socket, std::string query);
rather than having an increasingly large if else tree for every route im thinking of something like this
c++
class Router {
std::unordered_map<std::string, std::unordered_map<std::string, std::function<void()>>> router {};
};
c++
class Router {
std::unordered_map<std::string, std::unordered_map<std::string, std::function<void()>>> router {};
};
where router[URL][http method] will store the relevant controller now the major issue im having is not all controllers have the same number of arguments would anyone be able to help me with a design for my router class to circumvent this?
13 Replies
sigma
sigma9mo ago
If you don't want to use templating, why not let all routes get an "option<string>" object? If you don't want to pass anything, then option is going to be none. If you want to pass an argument, then it is going to have something Now, if you mean a dynamic number of arguments, then you might need to pass a vector, perhaps? Although I am not sure what you consider an "argument". Argument could be in the query string of the URL, but also as part of the URL, or even in the body of the request, if you are dealing with a POST request Now, if you want your routing to be defined statically, I am sure you can do some templating magic on this, unless you want your router to be adjusted dynamically Also, some routers even have parsing capabilities, but maybe you would like to leave this unimplemented if you want to leave it as a separate module
muscle aggregator 82
What’s wrong with using if-else? It’s probably not going to get more readable or performant by adding a template class with variadic arguments… the time you’re spending to solve this “issue” could have been spent doing other more important things. Keep it simple brother
mu5h1e
mu5h1eOP9mo ago
Yeah thats what im kinda thinking honestly It just felt like there might be a better way to handle it idk
sigma
sigma9mo ago
I mean, it doesn't seem that it would be a problem. If you find yourself repeating some parsing logic for some routes, then, it would be a good idea to come up with a parsing stage, but right now that doesn't seem to be the case
mu5h1e
mu5h1eOP9mo ago
Yeah Thanks everyone :))
Shiki
Shiki9mo ago
np 😉
muscle aggregator 82
🤨
Shiki
Shiki9mo ago
🤨
Shiki
Shiki9mo ago
No description
Want results from more Discord servers?
Add your server