Boost C++ Libraries

PrevUpHomeNext

Concepts

This chapter describes the named requirements and concepts that make up the public interface of Boost.Taar. Each concept is given a semantic description here; the formal C++ definitions live in the Reference chapter and can be reached from the entries below.

A Matcher is a callable that decides whether a given HTTP request belongs to a particular handler. Matchers are obtained by composing the matcher objects exported by boost::taar::matcher (method, target, header, cookie, version) with the relational and boolean operators defined in <boost/taar/matcher/operand.hpp>.

Required expressions

A type is a Matcher when a matcher::operand can be constructed from it. Besides the composed DSL expressions, that includes any callable returning bool that takes a boost::beast::http::request_header<> const& and a matcher::context&, optionally followed by a boost::urls::url_view const& (the parsed target), a cookies const& (the parsed Cookie headers), or both in either order. The session parses the target and the cookies only when some registered matcher asks for them.

Expression

Semantics

m(req, ctx)

Returns bool. May write to ctx.path_args and other context state; the context is cleared before each matcher runs.

m(req, ctx, url)

As above, with the request target parsed as a URL.

m(req, ctx, cookies)

As above, with the parsed cookies.

Metadata

A composed matcher is a matcher::operand<Callable, Metadata>. Metadata is a type-level AST (and_, or_, not_ over leaf tags such as method_eq_constraint and target_constraint), and captures() returns the values each leaf captured, in leaf order. Generators inspect the AST at compile time to decide whether they can express a route, and read the captures at run time. A plain callable used as a matcher has any_metadata and cannot be documented.

An Argument Provider is an object that, given an HTTP request, produces exactly one argument for a wrapped callable. Argument providers are supplied as the trailing arguments to taar::handler::rest.

The library exports path_arg, query_arg, query_list_arg (every occurrence of a query key, ?tag=a&tag=b, into a container), header_arg, cookie_arg, string_body_arg, json_body_arg, url_encoded_form_data_arg, multipart_form_arg, stream_body_arg, multipart_stream_arg, target_arg, body_size_arg and attribute_arg<T>() (a value an interceptor or guard attached to the request; not a client input, so documentation generators leave it out), plus with_default to substitute a value when a provider reports argument_not_found and constrained to validate the value. User code can define new argument providers by satisfying the required expressions.

Providers report through taar::result<V> (that is, boost::system::result<V, taar::failure>). The not-found signal is taar::failure{taar::error::argument_not_found}, with no message: it is the one failure that with_default and std::optional parameters absorb. Any other failure should carry a code that says what went wrong and a message that reads on its own, such as taar::failure{taar::error::argument_ambiguous, "header 'x-id' occurs more than once"}; the binder nests it as the cause of an invalid_argument_format failure naming the argument and its position (see Error mapping per surface).

Required expressions

Given a provider p, a request req whose body type the provider declares, and a matcher::context ctx:

Expression

Semantics

p(req, ctx)

Returns taar::result<V>. The value is passed through rest_arg_cast to the callable's parameter type. A failure f with f.is(taar::error::argument_not_found) means the argument is absent; any other failure is thrown as a taar::exception and reaches the soft error handler (or the JSON-RPC mapper, or the MCP tool error handler). A provider returning boost::system::result<V> with a plain error_code is still accepted; its code becomes a failure without a message.

p.name()

The argument's name, used in diagnostics and documentation.

p.description()

Optional. A human-readable description used by documentation generators. Named providers take it as a trailing constructor string; body providers take handler::description{...}.

The JSON-RPC and MCP layers have their own providers (rpc_arg, mcp_arg, uri_arg) with the same shape but a different first argument: the decoded call rather than the HTTP request.

Any user-defined return type can be converted to an HTTP response by overloading the boost::taar::response_from_tag tag (declared in <boost/taar/core/response_from_tag.hpp>). This extension point is the basis for the automatic JSON conversion of boost::json::value, boost::json::object and boost::json::array, the text conversion of strings and arithmetic types. (taar::handler::htdocs builds its responses itself, as a typed http::response<segmented_body>.)

rest_arg_cast is the extension point used by argument providers to turn a string view (or JSON value) extracted from the request into the typed argument of a callable. Customise it by overloading boost::taar::handler::rest_arg_cast_tag for your type. Types that boost::json::value_to understands, including boost::described structs, work without any overload.

A Context-aware handler opts in to receiving the contexts the session has in scope. The handlers produced by handler::rest, with_session, jsonrpc::endpoint::handler() and mcp::endpoint::handler() all satisfy it.

Expression

Semantics

H::context_aware

static constexpr bool, true.

typename H::request_type

The http::request<Body> the handler reads; the session parses the body accordingly.

h(ctxs, req, ctx)

ctxs is a handler::contexts<C...>, a tuple of shared_ptr<C>; req is request_type const&; ctx is matcher::context const&. Returns a response, an awaitable of one, or a streaming generator.

Handlers that are not context-aware keep the classic (request, matcher::context) signature. Wrappers such as with_session extend ctxs with their own object before calling the inner handler, so the set of types in scope grows outward-in.

A Registration observer is any callable accepting (matcher::operand const&, Handler const&), passed as a trailing argument to register_request_handler. It runs once, before the route is installed, and may inspect the operand's metadata and captures and the handler's params() and callable_result_type when present. openapi::generator::describe(...) returns one.


PrevUpHomeNext