197 using FunctionType = FUNCTION;
199 void handleHttpRequest(
200 std::deque<std::string> &pathArguments,
201 const HttpRequestPtr &req,
202 std::function<
void(
const HttpResponsePtr &)> &&callback)
override
204 if (!pathArguments.empty())
206 std::vector<std::string> args;
207 args.reserve(pathArguments.size());
208 for (
auto &arg : pathArguments)
210 args.emplace_back(arg);
212 req->setRoutingParameters(std::move(args));
214 run(pathArguments, req, std::move(callback));
217 size_t paramCount()
override
219 return traits::arity;
222 bool isStreamHandler()
override
224 return traits::isStreamHandler;
227 HttpBinder(FUNCTION &&func) : func_(std::forward<FUNCTION>(func))
229 static_assert(traits::isHTTPFunction,
230 "Your API handler function interface is wrong!");
236 std::cout <<
"argument_count=" << argument_count <<
" "
237 << traits::isHTTPFunction << std::endl;
240 const std::string &handlerName()
const override
245 template <
bool isClassFunction = traits::isClassFunction,
246 bool isDrObjectClass = traits::isDrObjectClass>
247 void createHandlerInstance()
249 if constexpr (isClassFunction)
251 if constexpr (isDrObjectClass)
254 typename traits::class_type>();
255 LOG_TRACE <<
"create handler class object: " << objPtr.get();
259 auto &obj = getControllerObj<typename traits::class_type>();
260 LOG_TRACE <<
"create handler class object: " << &obj;
267 template <std::
size_t Index>
268 using nth_argument_type =
typename traits::template argument<Index>;
270 static const size_t argument_count = traits::arity;
271 std::string handlerName_;
273 template <
typename... Values,
274 std::size_t Boundary = argument_count,
275 bool isStreamHandler = traits::isStreamHandler,
276 bool isCoroutine = traits::isCoroutine>
277 void run(std::deque<std::string> &pathArguments,
278 const HttpRequestPtr &req,
279 std::function<
void(
const HttpResponsePtr &)> &&callback,
282 if constexpr (
sizeof...(Values) < Boundary)
287 nth_argument_type<
sizeof...(Values)>>::isValid,
288 "your handler argument type must be value type or const left "
289 "reference type or right reference type");
290 using ValueType = std::remove_cv_t<
291 std::remove_reference_t<nth_argument_type<
sizeof...(Values)>>>;
292 if (!pathArguments.empty())
294 std::string v{std::move(pathArguments.front())};
295 pathArguments.pop_front();
301 getHandlerArgumentValue<ValueType>(std::move(v));
305 std::forward<Values>(values)...,
310 catch (
const std::exception &e)
312 handleException(e, req, std::move(callback));
320 auto value = req->as<ValueType>();
324 std::forward<Values>(values)...,
328 catch (
const std::exception &e)
330 handleException(e, req, std::move(callback));
335 LOG_ERROR <<
"Exception not derived from std::exception";
343 std::forward<Values>(values)...,
346 else if constexpr (
sizeof...(Values) == Boundary)
348 if constexpr (!isCoroutine)
354 if constexpr (isStreamHandler)
357 createRequestStream(req),
359 std::move(values)...);
363 callFunction(req, cb, std::move(values)...);
366 catch (
const std::exception &except)
368 handleException(except, req, std::move(callback));
372 LOG_ERROR <<
"Exception not derived from std::exception";
376#ifdef __cpp_impl_coroutine
379 static_assert(!isStreamHandler);
380 [
this](HttpRequestPtr req,
381 std::function<void(
const HttpResponsePtr &)> callback,
385 if constexpr (std::is_same_v<
387 typename traits::return_type>)
391 callFunction(req, cb, std::move(values)...);
393 else if constexpr (std::is_same_v<
395 typename traits::return_type>)
399 co_await callFunction(req,
401 std::move(values)...);
403 else if constexpr (std::is_same_v<
405 typename traits::return_type>)
408 co_await callFunction(req,
409 std::move(values)...);
410 callback(std::move(resp));
413 catch (
const std::exception &except)
415 handleException(except, req, std::move(callback));
420 <<
"Exception not derived from std::exception";
423 }(req, std::move(callback), std::move(values)...);
429 template <
typename... Values,
430 bool isClassFunction = traits::isClassFunction,
431 bool isDrObjectClass = traits::isDrObjectClass,
432 bool isNormal = std::is_same_v<
typename traits::first_param_type,
434 typename traits::return_type callFunction(
const HttpRequestPtr &req,
437 if constexpr (isNormal)
439 if constexpr (isClassFunction)
441 if constexpr (!isDrObjectClass)
444 getControllerObj<typename traits::class_type>();
445 return (obj.*func_)(req, std::move(values)...);
450 typename traits::class_type>();
451 return (*objPtr.*func_)(req, std::move(values)...);
456 return func_(req, std::move(values)...);
461 if constexpr (isClassFunction)
463 if constexpr (!isDrObjectClass)
466 getControllerObj<typename traits::class_type>();
467 return (obj.*func_)((*req), std::move(values)...);
472 typename traits::class_type>();
473 return (*objPtr.*func_)((*req), std::move(values)...);
478 return func_((*req), std::move(values)...);