## Class rest_controller

zeep::http::rest_controller — class that helps with handling REST requests

## Synopsis

    // 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 > or std::is_same_v< ResultType, reply >), int >  = 0>
          void invoke(ArgsTuple &&, reply &);
        template<typename ResultType, typename ArgsTuple,
                 std::enable_if_t< std::is_same_v< ResultType, reply >, 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 > or zeep::is_serializable_array_type_v< T, zeep::json::deserializer< json::element >>), 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 >> or zeep::is_serializable_array_type_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...);
    };

## Description

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` public construct/copy/destruct

1.     rest_controller(const std::string & prefix_path);

   constructor

   Parameters:

   `prefix_path` | This is the leading part of the request URI for each mount point

2.     ~rest_controller();

### `rest_controller` public member functions

1.     virtual bool handle_request(request & req, reply & rep);

   will do the hard work

### `rest_controller` protected member functions

1.     template<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.

2.     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

3.     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

4.     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

5.     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