forked from sony/nmos-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi_router.h
91 lines (75 loc) · 4.56 KB
/
api_router.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#ifndef CPPREST_API_ROUTER_H
#define CPPREST_API_ROUTER_H
#include <functional>
#include <list>
#include <unordered_map>
#include "cpprest/http_utils.h"
#include "cpprest/json_ops.h" // hmm, only for names used in using declarations
#include "cpprest/regex_utils.h" // hmm, only for types used in details functions
// api_router is an extension to http_listener that uses regexes to define route patterns
namespace web
{
namespace http
{
namespace experimental
{
namespace listener
{
// a using-directive with the following namespace makes defining routers less verbose
// using namespace api_router_using_declarations;
namespace api_router_using_declarations {}
typedef std::unordered_map<utility::string_t, utility::string_t> route_parameters;
// route handlers have access to the request, and a mutable response object, the route path and parameters extracted from it by the matched route pattern;
// a handler may e.g. reply to the request or initiate asynchronous processing, and returns a flag indicating whether to continue matching routes or not
typedef std::function<pplx::task<bool>(web::http::http_request req, web::http::http_response res, const utility::string_t& route_path, const route_parameters& parameters)> route_handler;
// api router implementation
namespace details
{
class api_router_impl;
enum match_flag_type { match_entire = 0, match_prefix = 1 };
utility::string_t get_route_relative_path(const web::http::http_request& req, const utility::string_t& route_path);
route_parameters get_parameters(const utility::named_sub_matches_t& parameter_sub_matches, const utility::smatch_t& route_match);
bool route_regex_match(const utility::string_t& path, utility::smatch_t& route_match, const utility::regex_t& route_regex, match_flag_type flags);
}
class api_router
{
public:
api_router();
// allow use as a handler with http_listener
void operator()(web::http::http_request req);
// allow use as a mounted handler in another api_router
pplx::task<bool> operator()(web::http::http_request req, web::http::http_response res, const utility::string_t& route_path, const route_parameters& parameters);
// add a method-specific handler to support requests for this route
void support(const utility::string_t& route_pattern, const web::http::method& method, route_handler handler);
// add a handler to support all other requests for this route (must be added after any method-specific handlers)
void support(const utility::string_t& route_pattern, route_handler all_handler);
// add a method-specific handler to support requests for this route and sub-routes
void mount(const utility::string_t& route_pattern, const web::http::method& method, route_handler handler);
// add a handler to support all other requests for this route and sub-routes (must be added after any method-specific handlers)
void mount(const utility::string_t& route_pattern, route_handler all_handler);
// pop back handler
void pop_back();
// provide an exception handler for this route and sub-routes (using std::current_exception, etc.)
void set_exception_handler(route_handler handler);
private:
std::shared_ptr<details::api_router_impl> impl;
};
// convenient using declarations to make defining routers less verbose
namespace api_router_using_declarations
{
using utility::string_t;
using web::http::experimental::listener::api_router;
using web::http::experimental::listener::route_parameters;
using web::http::http_request;
using web::http::http_response;
using web::http::methods;
using web::http::set_reply;
using web::http::status_codes;
using web::json::value;
using web::json::value_of;
}
}
}
}
}
#endif