ApiClient_define.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /***************************************************************************
  2. *
  3. * Project _____ __ ____ _ _
  4. * ( _ ) /__\ (_ _)_| |_ _| |_
  5. * )(_)( /(__)\ )( (_ _)(_ _)
  6. * (_____)(__)(__)(__) |_| |_|
  7. *
  8. *
  9. * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. *
  23. ***************************************************************************/
  24. /**[info]
  25. * This file contains "defines" for ApiClient code generating macro. <br>
  26. * Usage:<br>
  27. *
  28. * ```cpp
  29. * #include OATPP_CODEGEN_BEGIN(ApiClient)
  30. * ...
  31. * // Generated API-Calls.
  32. * ...
  33. * #include OATPP_CODEGEN_END(ApiClient)
  34. * ```
  35. *
  36. *
  37. * *For details see:*
  38. * <ul>
  39. * <li>[ApiClient component](https://oatpp.io/docs/components/api-client/)</li>
  40. * <li>&id:oatpp::web::client::ApiClient;</li>
  41. * </ul>
  42. */
  43. #include "oatpp/core/macro/basic.hpp"
  44. #include "oatpp/core/macro/codegen.hpp"
  45. #define OATPP_MACRO_API_CLIENT_PARAM_MACRO(MACRO, TYPE, PARAM_LIST) MACRO(TYPE, PARAM_LIST)
  46. #define OATPP_MACRO_API_CLIENT_PARAM_TYPE(MACRO, TYPE, PARAM_LIST) const TYPE&
  47. #define OATPP_MACRO_API_CLIENT_PARAM_NAME(MACRO, TYPE, PARAM_LIST) OATPP_MACRO_FIRSTARG PARAM_LIST
  48. #define OATPP_MACRO_API_CLIENT_PARAM_TYPE_STR(MACRO, TYPE, PARAM_LIST) #TYPE
  49. #define OATPP_MACRO_API_CLIENT_PARAM_NAME_STR(MACRO, TYPE, PARAM_LIST) OATPP_MACRO_FIRSTARG_STR PARAM_LIST
  50. #define OATPP_MACRO_API_CLIENT_PARAM(MACRO, TYPE, PARAM_LIST) (MACRO, TYPE, PARAM_LIST)
  51. #define HEADER(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_HEADER, TYPE, (__VA_ARGS__))
  52. #define PATH(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_PATH, TYPE, (__VA_ARGS__))
  53. #define QUERY(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_QUERY, TYPE, (__VA_ARGS__))
  54. #define BODY(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY, TYPE, (__VA_ARGS__))
  55. #define BODY_DTO(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY_DTO, TYPE, (__VA_ARGS__))
  56. #define BODY_STRING(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY_STRING, TYPE, (__VA_ARGS__))
  57. #define AUTHORIZATION(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_AUTHORIZATION, TYPE, (__VA_ARGS__))
  58. #define AUTHORIZATION_BASIC(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC, TYPE, (__VA_ARGS__))
  59. //////////////////////////////////////////////////////////////////////////
  60. #define OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(MACRO, TYPE, ...) \
  61. OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (TYPE, __VA_ARGS__))
  62. //////////////////////////////////////////////////////////////////////////
  63. // INIT
  64. /**
  65. * Codegen macoro to be used in classes extending &id:oatpp::web::client::ApiClient; to generate required fields/methods/constructors for ApiClient.
  66. * @param NAME - name of the ApiClient class.
  67. */
  68. #define API_CLIENT_INIT(NAME) \
  69. public: \
  70. NAME(const std::shared_ptr<oatpp::web::client::RequestExecutor>& requestExecutor, \
  71. const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper) \
  72. : oatpp::web::client::ApiClient(requestExecutor, objectMapper) \
  73. {} \
  74. public: \
  75. static std::shared_ptr<NAME> createShared(const std::shared_ptr<oatpp::web::client::RequestExecutor>& requestExecutor, \
  76. const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper){ \
  77. return std::make_shared<NAME>(requestExecutor, objectMapper); \
  78. }
  79. // HEADER MACRO
  80. #define OATPP_MACRO_API_CLIENT_HEADER_1(TYPE, NAME) \
  81. __headers.put_LockFree(#NAME, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
  82. #define OATPP_MACRO_API_CLIENT_HEADER_2(TYPE, NAME, QUALIFIER) \
  83. __headers.put_LockFree(QUALIFIER, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
  84. #define OATPP_MACRO_API_CLIENT_HEADER(TYPE, PARAM_LIST) \
  85. OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_HEADER_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
  86. // PATH MACRO
  87. #define OATPP_MACRO_API_CLIENT_PATH_1(TYPE, NAME) \
  88. __pathParams.insert({#NAME, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME)});
  89. #define OATPP_MACRO_API_CLIENT_PATH_2(TYPE, NAME, QUALIFIER) \
  90. __pathParams.insert({QUALIFIER, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME)});
  91. #define OATPP_MACRO_API_CLIENT_PATH(TYPE, PARAM_LIST) \
  92. OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_PATH_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
  93. // QUERY MACRO
  94. #define OATPP_MACRO_API_CLIENT_QUERY_1(TYPE, NAME) \
  95. __queryParams.insert({#NAME, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME)});
  96. #define OATPP_MACRO_API_CLIENT_QUERY_2(TYPE, NAME, QUALIFIER) \
  97. __queryParams.insert({QUALIFIER, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME)});
  98. #define OATPP_MACRO_API_CLIENT_QUERY(TYPE, PARAM_LIST) \
  99. OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_QUERY_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
  100. // BODY MACRO
  101. #define OATPP_MACRO_API_CLIENT_BODY(TYPE, PARAM_LIST) \
  102. __body = OATPP_MACRO_FIRSTARG PARAM_LIST;
  103. // BODY_DTO MACRO
  104. #define OATPP_MACRO_API_CLIENT_BODY_DTO(TYPE, PARAM_LIST) \
  105. __body = oatpp::web::protocol::http::outgoing::BufferBody::createShared( \
  106. m_objectMapper->writeToString(OATPP_MACRO_FIRSTARG PARAM_LIST), \
  107. m_objectMapper->getInfo().http_content_type \
  108. );
  109. // BODY_STRING MACRO
  110. #define OATPP_MACRO_API_CLIENT_BODY_STRING(TYPE, PARAM_LIST) \
  111. __body = oatpp::web::protocol::http::outgoing::BufferBody::createShared(OATPP_MACRO_FIRSTARG PARAM_LIST);
  112. // AUTHORIZATION MACRO
  113. #define OATPP_MACRO_API_CLIENT_AUTHORIZATION_2(TYPE, TOKEN, SCHEME) \
  114. __headers.put_LockFree("Authorization", String(SCHEME " ") + String(TOKEN));
  115. #define OATPP_MACRO_API_CLIENT_AUTHORIZATION(TYPE, PARAM_LIST) \
  116. OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
  117. // AUTHORIZATION_BASIC MACRO
  118. #define OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC_1(TYPE, TOKEN) \
  119. __headers.put_LockFree("Authorization", String("Basic ") + oatpp::encoding::Base64::encode(TOKEN));
  120. #define OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC(TYPE, PARAM_LIST) \
  121. OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
  122. // FOR EACH
  123. #define OATPP_MACRO_API_CLIENT_PARAM_DECL(INDEX, COUNT, X) \
  124. OATPP_MACRO_API_CLIENT_PARAM_TYPE X OATPP_MACRO_API_CLIENT_PARAM_NAME X,
  125. #define OATPP_MACRO_API_CLIENT_PARAM_PUT(INDEX, COUNT, X) \
  126. OATPP_MACRO_API_CLIENT_PARAM_MACRO X
  127. // API_CALL MACRO
  128. #define OATPP_API_CALL_0(NAME, METHOD, PATH) \
  129. const oatpp::data::share::StringTemplate Z_PATH_TEMPLATE_##NAME = parsePathTemplate(#NAME, PATH); \
  130. \
  131. static void Z_ADD_HEADERS_##NAME(oatpp::web::client::ApiClient::Headers& headers, ...) { \
  132. (void) headers; \
  133. } \
  134. \
  135. std::shared_ptr<oatpp::web::protocol::http::incoming::Response> NAME( \
  136. const std::shared_ptr<oatpp::web::client::RequestExecutor::ConnectionHandle>& __connectionHandle = nullptr \
  137. ) { \
  138. oatpp::web::client::ApiClient::Headers __headers; \
  139. Z_ADD_HEADERS_##NAME(__headers, 1); \
  140. std::shared_ptr<oatpp::web::protocol::http::outgoing::Body> body; \
  141. return executeRequest(METHOD, \
  142. Z_PATH_TEMPLATE_##NAME, \
  143. __headers, \
  144. {}, \
  145. {}, \
  146. body, \
  147. __connectionHandle); \
  148. }
  149. #define OATPP_API_CALL_1(NAME, METHOD, PATH, ...) \
  150. const oatpp::data::share::StringTemplate Z_PATH_TEMPLATE_##NAME = parsePathTemplate(#NAME, PATH); \
  151. \
  152. static void Z_ADD_HEADERS_##NAME(oatpp::web::client::ApiClient::Headers& headers, ...) { \
  153. (void) headers; \
  154. } \
  155. \
  156. std::shared_ptr<oatpp::web::protocol::http::incoming::Response> NAME(\
  157. OATPP_MACRO_FOREACH(OATPP_MACRO_API_CLIENT_PARAM_DECL, __VA_ARGS__) \
  158. const std::shared_ptr<oatpp::web::client::RequestExecutor::ConnectionHandle>& __connectionHandle = nullptr \
  159. ) { \
  160. oatpp::web::client::ApiClient::Headers __headers; \
  161. Z_ADD_HEADERS_##NAME(__headers, 1); \
  162. std::unordered_map<oatpp::String, oatpp::String> __pathParams; \
  163. std::unordered_map<oatpp::String, oatpp::String> __queryParams; \
  164. std::shared_ptr<oatpp::web::protocol::http::outgoing::Body> __body; \
  165. OATPP_MACRO_FOREACH(OATPP_MACRO_API_CLIENT_PARAM_PUT, __VA_ARGS__) \
  166. return executeRequest(METHOD, \
  167. Z_PATH_TEMPLATE_##NAME, \
  168. __headers, \
  169. __pathParams, \
  170. __queryParams, \
  171. __body, \
  172. __connectionHandle); \
  173. }
  174. // Chooser
  175. #define OATPP_API_CALL_MACRO_0(METHOD, PATH, NAME) \
  176. OATPP_API_CALL_0(NAME, METHOD, PATH)
  177. #define OATPP_API_CALL_MACRO_1(METHOD, PATH, NAME, ...) \
  178. OATPP_API_CALL_1(NAME, METHOD, PATH, __VA_ARGS__)
  179. /**
  180. * Codegen macoro to be used in `oatpp::web::client::ApiClient` to generate REST API-Calls.
  181. * @param METHOD - Http method ("GET", "POST", "PUT", etc.)
  182. * @param PATH - Path to endpoint (without host)
  183. * @param NAME - Name of the generated method
  184. * @return - std::shared_ptr to &id:oatpp::web::protocol::http::incoming::Response;
  185. */
  186. #define API_CALL(METHOD, PATH, ...) \
  187. OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_BINARY_SELECTOR(OATPP_API_CALL_MACRO_, (__VA_ARGS__)) (METHOD, PATH, __VA_ARGS__))
  188. // API_CALL_ASYNC MACRO
  189. #define OATPP_API_CALL_ASYNC_0(NAME, METHOD, PATH) \
  190. const oatpp::data::share::StringTemplate Z_PATH_TEMPLATE_##NAME = parsePathTemplate(#NAME, PATH); \
  191. \
  192. static void Z_ADD_HEADERS_##NAME(oatpp::web::client::ApiClient::Headers& headers, ...) { \
  193. (void) headers; \
  194. } \
  195. \
  196. oatpp::async::CoroutineStarterForResult<const std::shared_ptr<oatpp::web::protocol::http::incoming::Response>&> NAME( \
  197. const std::shared_ptr<oatpp::web::client::RequestExecutor::ConnectionHandle>& __connectionHandle = nullptr \
  198. ) { \
  199. oatpp::web::client::ApiClient::Headers __headers; \
  200. Z_ADD_HEADERS_##NAME(__headers, 1); \
  201. std::shared_ptr<oatpp::web::protocol::http::outgoing::Body> body; \
  202. return executeRequestAsync(METHOD, \
  203. Z_PATH_TEMPLATE_##NAME, \
  204. __headers, \
  205. {}, \
  206. {}, \
  207. body, \
  208. __connectionHandle); \
  209. }
  210. #define OATPP_API_CALL_ASYNC_1(NAME, METHOD, PATH, ...) \
  211. const oatpp::data::share::StringTemplate Z_PATH_TEMPLATE_##NAME = parsePathTemplate(#NAME, PATH); \
  212. \
  213. static void Z_ADD_HEADERS_##NAME(oatpp::web::client::ApiClient::Headers& headers, ...) { \
  214. (void) headers; \
  215. } \
  216. \
  217. oatpp::async::CoroutineStarterForResult<const std::shared_ptr<oatpp::web::protocol::http::incoming::Response>&> NAME(\
  218. OATPP_MACRO_FOREACH(OATPP_MACRO_API_CLIENT_PARAM_DECL, __VA_ARGS__) \
  219. const std::shared_ptr<oatpp::web::client::RequestExecutor::ConnectionHandle>& __connectionHandle = nullptr \
  220. ) { \
  221. oatpp::web::client::ApiClient::Headers __headers; \
  222. Z_ADD_HEADERS_##NAME(__headers, 1); \
  223. std::unordered_map<oatpp::String, oatpp::String> __pathParams; \
  224. std::unordered_map<oatpp::String, oatpp::String> __queryParams; \
  225. std::shared_ptr<oatpp::web::protocol::http::outgoing::Body> __body; \
  226. OATPP_MACRO_FOREACH(OATPP_MACRO_API_CLIENT_PARAM_PUT, __VA_ARGS__) \
  227. return executeRequestAsync(METHOD, \
  228. Z_PATH_TEMPLATE_##NAME, \
  229. __headers, \
  230. __pathParams, \
  231. __queryParams, \
  232. __body, \
  233. __connectionHandle); \
  234. }
  235. #define OATPP_API_CALL_ASYNC_MACRO_0(METHOD, PATH, NAME) \
  236. OATPP_API_CALL_ASYNC_0(NAME, METHOD, PATH)
  237. #define OATPP_API_CALL_ASYNC_MACRO_1(METHOD, PATH, NAME, ...) \
  238. OATPP_API_CALL_ASYNC_1(NAME, METHOD, PATH, __VA_ARGS__)
  239. /**
  240. * Codegen macro to be used in `oatpp::web::client::ApiClient` to generate Asynchronous REST API-Calls.
  241. * @param METHOD - Http method ("GET", "POST", "PUT", etc.)
  242. * @param PATH - Path to endpoint (without host)
  243. * @param NAME - Name of the generated method
  244. * @return - &id:oatpp::async::CoroutineStarterForResult;<const std::shared_ptr<&id:oatpp::web::protocol::http::incoming::Response;>&>.
  245. */
  246. #define API_CALL_ASYNC(METHOD, PATH, ...) \
  247. OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_BINARY_SELECTOR(OATPP_API_CALL_ASYNC_MACRO_, (__VA_ARGS__)) (METHOD, PATH, __VA_ARGS__))
  248. /**
  249. * Codegen macro to add default headers to API_CALL
  250. */
  251. #define API_CALL_HEADERS(NAME) \
  252. \
  253. static void Z_ADD_HEADERS_##NAME(oatpp::web::client::ApiClient::Headers& headers, int) { \
  254. Z_ADD_HEADERS_##NAME(headers); /* call first method */ \
  255. Z_ADD_DEFAULT_HEADERS_##NAME(headers); \
  256. } \
  257. \
  258. static void Z_ADD_DEFAULT_HEADERS_##NAME(oatpp::web::client::ApiClient::Headers& headers)