******************************************************************************** Extractor ******************************************************************************** Extractors provide a more convenient way to help users access information from the incoming ``request``. Users can specify as many extractors as compiler allows per handler. Path ================================================================================ Use ``path_of`` to extract path parameters into ``std::tuple`` or plain ``struct``. `Path Extractor Example `_ .. code-block:: cpp auto get_order_tuple(path_of> order) -> awaitable { auto [user, order_id] = order; co_return response::ok() .set_header(http::field::content_type, mime::text_plain()) .set_body(fmt::format("user: {}, order_id: {}", user, order_id)); } struct order_t { std::string user; std::uint64_t order_id; }; auto get_order_struct(path_of order) -> awaitable { co_return response::ok() .set_header(http::field::content_type, mime::text_plain()) .set_body( fmt::format("user: {}, order_id: {}", order.user, order.order_id)); } int main() { auto ioc = net::io_context(); auto server = http_server::builder(ioc) .serve(route::get<"/tuple/users/{user}/orders/{order_id}">( get_order_tuple)) .serve(route::get<"/struct/users/{user}/orders/{order_id}">( get_order_struct)) .build(); server.bind("127.0.0.1", 8080); ioc.run(); } Query ================================================================================ Use ``query_of`` to extract query string parameters into plain ``struct``. `Query Extractor Example `_ .. code-block:: cpp struct order_t { std::string user; std::uint64_t order_id; }; auto get_order(query_of order) -> awaitable { co_return response::ok() .set_header(http::field::content_type, mime::text_plain()) .set_body( fmt::format("user: {}, order_id: {}", order.user, order.order_id)); } Form ================================================================================ Use ``form_of`` to extract urlencoded form from body into plain ``struct``. `Form Extractor Example `_ .. code-block:: cpp namespace api::v1::login { struct user_t { std::string username; std::string password; }; auto api(form_of user) -> awaitable { if (user.username != "fitoria" || user.password != "123456") { co_return response::unauthorized().build(); } co_return response::ok().build(); } } State ================================================================================ Use ``state_of`` to extract shared states. Note that unlike ``request::state()`` which returns ``optional``, ``state_of`` extractor *copy the value*. `State Extractor Example `_ .. code-block:: cpp using counter_t = std::atomic; auto get_index(state_of> counter) -> awaitable { co_return response::ok() .set_header(http::field::content_type, mime::text_plain()) .set_body(fmt::format("index page has been acquired {} times.", counter->fetch_add(1, std::memory_order_relaxed))); } .. note:: To enable extractor for custom type, implement customization point ``from_request_t``. Built-in Extractors ================================================================================ +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | Extractor | Description | Body Extractor | | +=======================+===========================================================+================+======================================================================================================+ | ``web::request`` | Extract whole ``request``. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``http::version`` | Extract HTTP version. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``http::header_map`` | Extract headers from request headers. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::connect_info`` | Extract connection info. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::path_info`` | Extract path info parameter. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::path_of`` | Extract path parameter into type ``T``. | no | * ``T = std::tuple``, parameters are extracted in the order where they are in the path. | | | | | * ``T = aggregate``, parameters are extracted to the field of their name. | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::query_map`` | Extract query string parameters. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::query_of`` | Extract query string parameters into type ``T`` | no | ``T = aggregate``, parameters are extracted to the field of their name. | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::state_of`` | Extract shared state of type ``T``. | no | Note that unlike ``request::state()`` which returns ``optional``, extractor *copy the value*. | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::websocket`` | Extract as websocket. | no | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::form_of`` | Extract urlencoded form from body into type ``T`` | yes | ``T = aggregate``, parameters are extracted to the field of their name. | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``web::json_of`` | Extract body and parse it into json and convert to ``T``. | yes | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``std::string`` | Extract body as ``std::string``. | yes | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ | ``std::vector`` | Extract body as ``std::vector``. | yes | | +-----------------------+-----------------------------------------------------------+----------------+------------------------------------------------------------------------------------------------------+ .. note:: The **body extractor** can only be used at most once in the request handlers since it consumes the body.