Closed guteksan closed 4 years ago
Hi!
I don't fully understand your issue. Why you can't just do something like that:
auto server_handler(Endpoint1_Handler & h1, Endpoint2_Handler &h2)
{
auto router = std::make_unique<router_t>();
router->http_get("/endpoint1", [&h1](auto req, auto param) {
// work on response using h1 outliving lambda
return req->create_response() ...
});
router->http_get("/endpoint2", [&h2](auto req, auto param) {
// work on response using h2 outliving lambda
return req->create_response() ...
});
return router;
}
...
Endpoint1_Handler h1;
Endpoint2_Handler h2;
restinio::run(
restinio::on_this_thread<traits_t>()
.port(2001)
.address("0.0.0.0")
.request_handler(server_handler(h1, h2))
);
?
Yes, this solution has also occured to me, but I thought that maybe there is a better solution, when Express Router and Endpoint Handlers have bound lifetime. I was curious what is the intended way of solving such issues in Restinio. Thank you for suggesting this and your prompt response.
At the moment RESTinio has no way to bind some resource lifetime to the lifetime of RESTinio's service. But if you want some lifetime bounds you can consider the usage of std::shared_ptr
:
auto server_handler(
const std::shared_ptr<Endpoint1_Handler> & h1,
const std::shared_ptr<Endpoint2_Handler> & h2)
{
auto router = std::make_unique<router_t>();
// NOTE: h1 is captured by value.
router->http_get("/endpoint1", [h1](auto req, auto param) {
// work on response using h1 outliving lambda
return req->create_response() ...
});
// NOTE: h2 is captured by value.
router->http_get("/endpoint2", [h2](auto req, auto param) {
// work on response using h2 outliving lambda
return req->create_response() ...
});
return router;
}
...
auto h1 = std::make_shared<Endpoint1_Handler>(...);
auto h2 = std::make_shared<Endpoint2_Handler>(...);
restinio::run(
restinio::on_this_thread<traits_t>()
.port(2001)
.address("0.0.0.0")
.request_handler(server_handler(h1, h2))
);
In that case you will have the guarantee that h1 and h2 will live while your request handlers live.
Thank you
In my project, for each endpoint I would like to have an object of, say, Endpoint_Handler, which lives for the service lifetime and handles incoming requests for this endpoint. I have a problem applying this using Express Router. Have a look at the code:
I would like to avoid creating Endpoint_Handler each time the request has come, but using lambda allows me to use only objects from the lambda scope. Normally, it could be solved by passing external objects as lambda captures. The problem is, that with this design pattern it can't be guaranteed that the captured object lives as long as the router. Apparently, I can't also extend router to contain some long living objects that can be used for handling requests. And of course, I would like to avoid using global objects.
Could you please suggest a solution, how this problem could be resolved with restinio, preferably with the Express Router?