![]() |
zeep::http::rest_controller — class that helps with handling REST requests
// In header: <zeep/http/rest-controller.hpp> class rest_controller : public zeep::http::controller { public: // member classes/structs/unions template<typename Callback, typename... > struct mount_point { }; template<typename ControllerType, typename Result, typename... Args> struct mount_point<Result(ControllerType::*)(Args...)> : public zeep::http::rest_controller::mount_point_base { // types typedef Result(ControllerType::*)(Args...) Sig; typedef std::tuple< typename std::remove_const_t< typename std::remove_reference_t< Args > >... > ArgsTuple; typedef typename std::remove_const_t< typename std::remove_reference_t< Result > > ResultType; typedef std::function< ResultType(Args...)> Callback; // construct/copy/destruct template<typename... Names> mount_point(const char *, const std::string &, rest_controller *, Sig, Names...); // public member functions virtual void call(const parameter_pack &, reply &); template<typename ResultType, typename ArgsTuple, std::enable_if_t< std::is_void_v< ResultType >, int > = 0> void invoke(ArgsTuple &&, reply &); template<typename ResultType, typename ArgsTuple, std::enable_if_t< not std::is_void_v< ResultType >, int > = 0> void invoke(ArgsTuple &&, reply &); void set_reply(reply &, std::filesystem::path); void set_reply(reply &, zeep::json::element &&); template<typename T> void set_reply(reply &, T &&); template<std::size_t... I> ArgsTuple collect_arguments(const parameter_pack &, std::index_sequence< I... >); bool get_parameter(const parameter_pack &, const char *, bool); std::string get_parameter(const parameter_pack &, const char *, std::string); file_param get_parameter(const parameter_pack &, const char *, file_param); std::vector< file_param > get_parameter(const parameter_pack &, const char *, std::vector< file_param >); json::element get_parameter(const parameter_pack &, const char *, json::element); template<typename T> std::optional< T > get_parameter(const parameter_pack &, const char *, std::optional< T >); std::optional< std::string > get_parameter(const parameter_pack &, const char *, std::optional< std::string >); template<typename T, std::enable_if_t< not(zeep::has_serialize_v< T, zeep::json::deserializer< json::element >> or std::is_enum_v< T >), int > = 0> T get_parameter(const parameter_pack &, const char *, T); template<typename T, unspecified = 0> T get_parameter(const parameter_pack &, const char *, T); template<typename T, std::enable_if_t< zeep::has_serialize_v< T, zeep::json::deserializer< json::element >>, int > = 0> T get_parameter(const parameter_pack &, const char *, T); // public data members static constexpr size_t N; Callback m_callback; std::array< const char *, N > m_names; }; // abstract base class for mount points struct mount_point_base { // construct/copy/destruct mount_point_base(const char *, const std::string &); ~mount_point_base(); // public member functions virtual void call(const parameter_pack &, reply &) = 0; // public data members std::string m_path; std::string m_method; std::regex m_rx; std::vector< std::string > m_path_params; }; // helper class for pulling parameter values out of the request struct parameter_pack { // construct/copy/destruct parameter_pack(const request &); // public member functions std::string get_parameter(const char *) const; std::tuple< std::string, bool > get_parameter_ex(const char *) const; std::vector< std::string > get_parameters(const char *) const; file_param get_file_parameter(const char *) const; std::vector< file_param > get_file_parameters(const char *) const; // public data members const request & m_req; std::vector< param > m_path_parameters; }; // construct/copy/destruct rest_controller(const std::string &); ~rest_controller(); // public member functions virtual bool handle_request(request &, reply &); // protected member functions template<typename Callback, typename... ArgNames> void map_request(const char *, const std::string &, Callback, ArgNames...); template<typename Callback, typename... ArgNames> void map_post_request(const char *, Callback, ArgNames...); template<typename Sig, typename... ArgNames> void map_put_request(const char *, Sig, ArgNames...); template<typename Sig, typename... ArgNames> void map_get_request(const char *, Sig, ArgNames...); template<typename Sig, typename... ArgNames> void map_delete_request(const char *, Sig, ArgNames...); };
This controller will handle REST requests. (See https://restfulapi.net/ for more info on REST)
To use this, create a subclass and add some methods that should be exposed. Then map these methods on a path that optionally contains parameter values.
See the chapter on REST controllers in the documention for more information.
rest_controller
protected member functionstemplate<typename Callback, typename... ArgNames> void map_request(const char * mountPoint, const std::string & method, Callback callback, ArgNames... names);map mountPoint in URI space to callback and map the arguments in this callback to parameters passed with names
The mountPoint parameter is the local part of the mount point. It can contain parameters enclosed in curly brackets.
For example, say we need a REST call to get the status of shoppingcart where the browser will send: `GET /ajax/cart/1234/status`
Our callback will look like this, for a class my_ajax_handler constructed with prefixPath /ajax
:
CartStatus my_ajax_handler::handle_get_status(int id);
Then we mount this callback like this:
map_get_request("/cart/{id}/status", &my_ajax_handler::handle_get_status, "id");
The number of names of the paramers specified should be equal to the number of actual arguments for the callback, otherwise the compiler will complain.
Arguments not found in the path will be fetched from the payload in case of a POST or from the URI parameters otherwise.
template<typename Callback, typename... ArgNames> void map_post_request(const char * mountPoint, Callback callback, ArgNames... names);map a POST to mountPoint in URI space to callback and map the arguments in this callback to parameters passed with names
template<typename Sig, typename... ArgNames> void map_put_request(const char * mountPoint, Sig callback, ArgNames... names);map a PUT to mountPoint in URI space to callback and map the arguments in this callback to parameters passed with names
template<typename Sig, typename... ArgNames> void map_get_request(const char * mountPoint, Sig callback, ArgNames... names);map a GET to mountPoint in URI space to callback and map the arguments in this callback to parameters passed with names
template<typename Sig, typename... ArgNames> void map_delete_request(const char * mountPoint, Sig callback, ArgNames... names);map a DELETE to mountPoint in URI space to callback and map the arguments in this callback to parameters passed with names