Open GitSparTV opened 1 month ago
Library provides good experience by providing variadic template interface in HTTP methods, however, you can't template-ly select HTTP method to call.
For example, you have myGet function:
myGet
template <class... Ts> cpr::Response myGet(Ts&&... ts) { return cpr::Get(cpr::Bearer{"ACCESS_TOKEN"}, cpr::Header{{"Content-Type", "application/json; charset=utf-8"}}); }
It's great, the headers will always be in the request. However, you also need the same wrapper for POST method. I can duplicate code, but it's lame.
The other way is to provide the function to myGet (ignore the name):
template <typename F, class... Ts> cpr::Response myGet(F f, Ts&&... ts) { return f(std::forward<Ts>(ts)..., cpr::Bearer{"ACCESS_TOKEN"}, cpr::Header{{"Content-Type", "application/json; charset=utf-8"}}); }
The solution will not make you happy:
cpr::Response r = myGet(cpr::Post<cpr::Url, cpr::Body, cpr::Bearer, cpr::Header>, cpr::Url{"http://www.httpbin.org/post?a=b"}, cpr::Body{"{\"a\": true}"});
You have to specify template parameters for cpr::Post and it looks worse than making a duplicate.
cpr::Post
Add HTTPMethod and a universal template to make a request.
HTTPMethod
#include <cpr/cpr.h> namespace cpr { enum class HTTPMethod { kGet, kHead, kPost, kPut, kDelete, kOptions, kPatch, }; template <HTTPMethod method, typename... Ts> Response Request(Ts&&... ts) { cpr::Session session; cpr::priv::set_option(session, std::forward<Ts>(ts)...); using enum HTTPMethod; if constexpr (method == kGet) { return session.Get(); } else if constexpr (method == kHead) { return session.Head(); } else if constexpr (method == kPost) { return session.Post(); } else if constexpr (method == kPut) { return session.Put(); } else if constexpr (method == kDelete) { return session.Delete(); } else if constexpr (method == kOptions) { return session.Options(); } else if constexpr (method == kPatch) { return session.Patch(); } else { static_assert(method == kGet, "Unknown method"); } } } template <cpr::HTTPMethod method, class... Ts> cpr::Response MyResponse(Ts&&... ts) { return Request<method>(std::forward<Ts>(ts)..., cpr::Bearer{"ACCESS_TOKEN"}, cpr::Header{{"Content-Type", "application/json; charset=utf-8"}}); } int main() { cpr::Response r = MyResponse<cpr::HTTPMethod::kPost>(cpr::Url{"http://www.httpbin.org/post?a=b"}, cpr::Body{"{\"a\": true}"}); std::cout << r.text << std::endl; }
No response
@GitSparTV I like this approach. Would you like to create a PR for this?
@COM8
Sure
Is your feature request related to a problem?
Library provides good experience by providing variadic template interface in HTTP methods, however, you can't template-ly select HTTP method to call.
For example, you have
myGet
function:It's great, the headers will always be in the request. However, you also need the same wrapper for POST method. I can duplicate code, but it's lame.
The other way is to provide the function to
myGet
(ignore the name):The solution will not make you happy:
You have to specify template parameters for
cpr::Post
and it looks worse than making a duplicate.Possible Solution
Add
HTTPMethod
and a universal template to make a request.Alternatives
Additional Context
No response