From eef0ee8729b359c754db29211fbdc5a489d4cea6 Mon Sep 17 00:00:00 2001 From: antao Date: Sat, 20 Oct 2018 12:40:30 +0800 Subject: [PATCH] Use 'any' to support two types of constraints --- examples/simple_example/api_Attachment.h | 2 +- examples/simple_example/api_v1_ApiTest.h | 26 +++++++++---------- lib/inc/drogon/HttpApiController.h | 33 ++++++++++++++++++++---- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/examples/simple_example/api_Attachment.h b/examples/simple_example/api_Attachment.h index d37f4881..cc433884 100644 --- a/examples/simple_example/api_Attachment.h +++ b/examples/simple_example/api_Attachment.h @@ -8,7 +8,7 @@ class Attachment : public drogon::HttpApiController public: METHOD_LIST_BEGIN //use METHOD_ADD to add your custom processing function here; - registerMethod(&Attachment::get, "/", {HttpRequest::Post}); + METHOD_ADD(Attachment::get, "/", HttpRequest::Post); METHOD_LIST_END //your declaration of processing function maybe like this: diff --git a/examples/simple_example/api_v1_ApiTest.h b/examples/simple_example/api_v1_ApiTest.h index 89a7f6a7..f355ef88 100755 --- a/examples/simple_example/api_v1_ApiTest.h +++ b/examples/simple_example/api_v1_ApiTest.h @@ -7,19 +7,19 @@ namespace v1 { class ApiTest : public drogon::HttpApiController { - public: - METHOD_LIST_BEGIN - //use METHOD_ADD to add your custom processing function here; - registerMethod(&ApiTest::get, "/get/{2}/{1}", {},{"drogon::GetFilter"}); //path will be /api/v1/apitest/get/{arg2}/{arg1} - registerMethod(&ApiTest::your_method_name, "/{1}/List?P2={2}", {HttpRequest::Get}); //path will be /api/v1/apitest/{arg1}/list - registerMethod(&ApiTest::staticApi, "/static",{HttpRequest::Get,HttpRequest::Post}); - METHOD_ADD(ApiTest::get2, "/get/{1}", "drogon::GetFilter"); - METHOD_LIST_END - //your declaration of processing function maybe like this: - void get(const HttpRequestPtr &req, const std::function &callback, int p1, std::string &&p2); - void your_method_name(const HttpRequestPtr &req, const std::function &callback, double p1, int p2) const; - void staticApi(const HttpRequestPtr &req, const std::function &callback); - void get2(const HttpRequestPtr &req, const std::function &callback, std::string &&p1); +public: + METHOD_LIST_BEGIN + //use METHOD_ADD to add your custom processing function here; + METHOD_ADD(ApiTest::get, "/get/{2}/{1}", "drogon::GetFilter"); //path will be /api/v1/apitest/get/{arg2}/{arg1} + METHOD_ADD(ApiTest::your_method_name, "/{1}/List?P2={2}", HttpRequest::Get); //path will be /api/v1/apitest/{arg1}/list + METHOD_ADD(ApiTest::staticApi, "/static", HttpRequest::Get, HttpRequest::Post); + METHOD_ADD(ApiTest::get2, "/get/{1}", "drogon::GetFilter"); + METHOD_LIST_END + //your declaration of processing function maybe like this: + void get(const HttpRequestPtr &req, const std::function &callback, int p1, std::string &&p2); + void your_method_name(const HttpRequestPtr &req, const std::function &callback, double p1, int p2) const; + void staticApi(const HttpRequestPtr &req, const std::function &callback); + void get2(const HttpRequestPtr &req, const std::function &callback, std::string &&p1); }; } // namespace v1 } // namespace api diff --git a/lib/inc/drogon/HttpApiController.h b/lib/inc/drogon/HttpApiController.h index 5e02e64f..483045ac 100755 --- a/lib/inc/drogon/HttpApiController.h +++ b/lib/inc/drogon/HttpApiController.h @@ -25,9 +25,9 @@ static void initMethods() \ { -#define METHOD_ADD(method, pattern, filters...) \ - { \ - registerMethod(&method, pattern, {}, {filters}); \ +#define METHOD_ADD(method, pattern, filters...) \ + { \ + registerMethod(&method, pattern, {filters}); \ } #define METHOD_LIST_END \ @@ -45,14 +45,37 @@ class HttpApiController : public DrObject template static void registerMethod(FUNCTION &&function, const std::string &pattern, - const std::vector &validMethods = std::vector(), - const std::vector &filters = std::vector()) + const std::vector &filtersAndMethods = std::vector()) { std::string path = std::string("/") + HttpApiController::classTypeName(); LOG_TRACE << "classname:" << HttpApiController::classTypeName(); //transform(path.begin(), path.end(), path.begin(), tolower); std::string::size_type pos; + + std::vector validMethods; + std::vector filters; + for (auto &filterOrMethod : filtersAndMethods) + { + if (filterOrMethod.type() == typeid(std::string)) + { + filters.push_back(*any_cast(&filterOrMethod)); + } + else if (filterOrMethod.type() == typeid(const char *)) + { + filters.push_back(*any_cast(&filterOrMethod)); + } + else if (filterOrMethod.type() == typeid(HttpRequest::Method)) + { + validMethods.push_back(*any_cast(&filterOrMethod)); + } + else + { + std::cerr << "Invalid controller constraint type:" << filterOrMethod.type().name() << std::endl; + LOG_ERROR << "Invalid controller constraint type"; + exit(1); + } + } while ((pos = path.find("::")) != std::string::npos) { path.replace(pos, 2, "/");