|
1 | 1 | # ApiClient-Demo Example
|
2 | 2 | Example project of how-to use oatpp ```ApiClient``` and how it works
|
3 | 3 |
|
4 |
| -More about oat++: |
5 |
| -- Website: [https://oatpp.io](https://oatpp.io) |
6 |
| -- ```ApiClient``` docs: [https://oatpp.io/docs/component/api-client](https://oatpp.io/docs/component/api-client) |
7 |
| -- Oat++ Repo: [https://github.com/oatpp/oatpp](https://github.com/oatpp/oatpp) |
| 4 | +# This example is moved to separate repo |
| 5 | +[https://github.com/oatpp/example-api-client](https://github.com/oatpp/example-api-client) |
8 | 6 |
|
9 |
| -## About ApiClient |
10 |
| - |
11 |
| -oatpp ```ApiClient``` is a mechanism which enables you to generate Web Api Clients in declarative manner. |
12 |
| -Under the hood it uses provided ```RequestExecutor``` to perform http requests. Thus you are abstracted from the low-level http-client library implementation and can substitute any other http-client library at any time with zero code changes. |
13 |
| -*Roughly you may treat oatpp ```ApiClient``` as Java Retrofit for C++.* |
14 |
| - |
15 |
| -In this example you can configure to use such RequestExecutors: |
16 |
| -- [oatpp-curl](https://github.com/oatpp/oatpp-curl) - RequestExecutor for oatpp's ApiClient based on libcurl. |
17 |
| -- ```oatpp::web::client::HttpRequestExecutor``` - oatpp out-of-the-box provided RequestExecutor |
18 |
| - |
19 |
| -## Example overview |
20 |
| - |
21 |
| -In this example you will find: |
22 |
| -- ```ApiClient``` built for http://httpbin.org/ web service. |
23 |
| -- Simple (Synchronous) API calls example. |
24 |
| -- Async API calls example processed with ```oatpp::async::Processor``` and ```oatpp::async::Coroutine```. |
25 |
| - |
26 |
| -#### Files and Folders |
27 |
| - |
28 |
| -``` |
29 |
| -- src/ |
30 |
| - |- DemoApiClient.hpp // ApiClient built for http://httpbin.org/ web service |
31 |
| - |- DemoApiModels.hpp // DTOs objects for DemoApiClient |
32 |
| - |- SimpleExample.hpp // Simple (Synchronous) API calls example |
33 |
| - |- AsyncExample.hpp // Async API calls example |
34 |
| - |- main.cpp // main is here |
35 |
| -``` |
36 |
| - |
37 |
| -#### ApiClient declaration overview |
38 |
| - |
39 |
| -Use ```API_CALL``` for simple (synchronous) calls. |
40 |
| -Use ```API_CALL_ASYNC``` for non-blocking Async calls. |
41 |
| - |
42 |
| -```c++ |
43 |
| -class DemoApiClient : public oatpp::web::client::ApiClient { |
44 |
| -#include OATPP_CODEGEN_BEGIN(ApiClient) |
45 |
| - |
46 |
| - API_CLIENT_INIT(DemoApiClient) |
47 |
| - |
48 |
| - ... |
49 |
| - |
50 |
| - API_CALL("GET", "get", doGet) |
51 |
| - API_CALL("POST", "post", doPost, BODY_STRING(String, body)) |
52 |
| - |
53 |
| - ... |
54 |
| - |
55 |
| - API_CALL_ASYNC("GET", "get", doGetAsync) |
56 |
| - API_CALL_ASYNC("POST", "post", doPostAsync, BODY_STRING(String, body)) |
57 |
| - |
58 |
| - ... |
59 |
| - |
60 |
| -#include OATPP_CODEGEN_END(ApiClient) |
61 |
| -}; |
62 |
| -``` |
63 |
| -
|
64 |
| -#### Example calls overview |
65 |
| -
|
66 |
| -##### SimpleExample.hpp |
67 |
| -
|
68 |
| -```c++ |
69 |
| -{ |
70 |
| - auto data = client->doGet()->readBodyToString(); |
71 |
| - OATPP_LOGD(TAG, "[doGet] data='%s'", data->c_str()); |
72 |
| -} |
73 |
| -
|
74 |
| -{ |
75 |
| - auto data = client->doPost("Some data passed to POST")->readBodyToString(); |
76 |
| - OATPP_LOGD(TAG, "[doPost] data='%s'", data->c_str()); |
77 |
| -} |
78 |
| -``` |
79 |
| - |
80 |
| -##### AsyncExample.hpp |
81 |
| - |
82 |
| -```c++ |
83 |
| -class SendCoroutine : public oatpp::async::Coroutine<SendCoroutine> { |
84 |
| -private: |
85 |
| - std::shared_ptr<DemoApiClient> m_client; |
86 |
| -public: |
87 |
| - |
88 |
| - SendCoroutine(const std::shared_ptr<DemoApiClient> client) : m_client(client) {} |
89 |
| - |
90 |
| - Action act() override { |
91 |
| - return m_client->doPostAsync(this, &SendDtoCoroutine::onResponse, "<POST-DATA-HERE>"); |
92 |
| - } |
93 |
| - |
94 |
| - Action onResponse(const std::shared_ptr<Response>& response) { |
95 |
| - return response->readBodyToStringAsync(this, &SendDtoCoroutine::onBody); |
96 |
| - } |
97 |
| - |
98 |
| - Action onBody(const oatpp::String& body) { |
99 |
| - OATPP_LOGD(TAG, "[SendCoroutine. doPostAsync] data='%s'", body->c_str()); |
100 |
| - return finish(); |
101 |
| - } |
102 |
| - |
103 |
| -}; |
104 |
| -``` |
105 |
| -
|
106 |
| -#### Request executor configuration |
107 |
| -
|
108 |
| -In ```main.cpp``` method ```run```. |
109 |
| -Try to substitute different ```RequestExecutors``` by switching from Curl to oatpp built-in request executor. |
110 |
| -
|
111 |
| -```c++ |
112 |
| -
|
113 |
| -void run(){ |
114 |
| - |
115 |
| - /* Create ObjectMapper for serialization of DTOs */ |
116 |
| - auto objectMapper = oatpp::parser::json::mapping::ObjectMapper::createShared(); |
117 |
| - |
118 |
| - /* Create RequestExecutor which will execute ApiClient's requests */ |
119 |
| - //auto requestExecutor = createOatppExecutor(); // <-- Uncomment this |
120 |
| - auto requestExecutor = createCurlExecutor(); // <-- Comment this |
121 |
| - |
122 |
| - /* DemoApiClient uses DemoRequestExecutor and json::mapping::ObjectMapper */ |
123 |
| - /* ObjectMapper passed here is used for serialization of outgoing DTOs */ |
124 |
| - auto client = DemoApiClient::createShared(requestExecutor, objectMapper); |
125 |
| - |
126 |
| - SimpleExample::runExample(client); |
127 |
| - AsyncExample::runExample(client); |
128 |
| - |
129 |
| -} |
130 |
| -
|
131 |
| -``` |
132 |
| - |
133 |
| -## Requires |
134 |
| - |
135 |
| -libcurl installed. |
136 |
| - |
137 |
| -*you may build this example without libcurl but then you'll have to remove libcurl/otpp-curl references in the code manually* |
138 |
| - |
139 |
| -## Build and run |
140 |
| - |
141 |
| -1) Git-Clone examples repo: |
142 |
| -``` |
143 |
| -$ git clone --recurse-submodules https://github.com/oatpp/oatpp-examples |
144 |
| -``` |
145 |
| -2) CD to this example |
146 |
| -``` |
147 |
| -$ cd oatpp-examples/ApiClient-Demo/ |
148 |
| -``` |
149 |
| -3) Modify ```build_app.sh``` to contain proper paths to ```curl/include``` and ```curl/lib``` |
150 |
| - |
151 |
| -4) Build project |
152 |
| -``` |
153 |
| -$ ./build_app.sh |
154 |
| -``` |
155 |
| -This will just call g++ |
156 |
| - |
157 |
| -5) Run app |
158 |
| -``` |
159 |
| -./run_app |
160 |
| -``` |
161 |
| - |
162 |
| -enjoy! |
163 |
| - |
164 |
| -## Note |
165 |
| -If you can't build app.- probably you need to [install build-essential](https://www.google.com.ua/search?q=install+build-essentials) |
166 |
| - |
167 |
| -### Xcode, MAC |
168 |
| -Xcode project included |
169 |
| - |
170 |
| -## More |
171 |
| -- [oatpp-curl](https://github.com/oatpp/oatpp-curl) - RequestExecutor for oatpp's ApiClient based on libcurl. |
172 |
| -- [oatpp-consul](https://github.com/oatpp/oatpp-consul) - oatpp-consul integration based on ```ApiClient```. |
0 commit comments