Struct aws_smithy_http_server::plugin::PluginPipeline
source · pub struct PluginPipeline<P>(_);Expand description
A wrapper struct for composing Plugins.
It is used as input for the builder_with_plugins method on the generate service struct
(e.g. PokemonService::builder_with_plugins).
Applying plugins in a sequence
You can use the push method to apply a new plugin after the ones that
have already been registered.
use aws_smithy_http_server::plugin::PluginPipeline;
let pipeline = PluginPipeline::new().push(LoggingPlugin).push(MetricsPlugin);The plugins’ runtime logic is executed in registration order.
In our example above, LoggingPlugin would run first, while MetricsPlugin is executed last.
Wrapping the current plugin pipeline
From time to time, you might have a need to transform the entire pipeline that has been built so far - e.g. you only want to apply those plugins for a specific operation.
PluginPipeline is itself a Plugin: you can apply any transformation that expects a
Plugin to an entire pipeline. In this case, we want to use
filter_by_operation_name to limit the scope of
the logging and metrics plugins to the CheckHealth operation:
use aws_smithy_http_server::plugin::{filter_by_operation_name, PluginPipeline};
// The logging and metrics plugins will only be applied to the `CheckHealth` operation.
let operation_specific_pipeline = filter_by_operation_name(
PluginPipeline::new()
.push(LoggingPlugin)
.push(MetricsPlugin),
|name| name == CheckHealth::NAME
);
let pipeline = PluginPipeline::new()
.push(operation_specific_pipeline)
// The auth plugin will be applied to all operations
.push(AuthPlugin);Concatenating two plugin pipelines
PluginPipeline is a good way to bundle together multiple plugins, ensuring they are all
registered in the correct order.
Since PluginPipeline is itself a Plugin, you can use the push to
append, at once, all the plugins in another pipeline to the current pipeline:
use aws_smithy_http_server::plugin::{IdentityPlugin, PluginPipeline, PluginStack};
pub fn get_bundled_pipeline() -> PluginPipeline<PluginStack<MetricsPlugin, PluginStack<LoggingPlugin, IdentityPlugin>>> {
PluginPipeline::new().push(LoggingPlugin).push(MetricsPlugin)
}
let pipeline = PluginPipeline::new()
.push(AuthPlugin)
.push(get_bundled_pipeline());Providing custom methods on PluginPipeline
You use an extension trait to add custom methods on PluginPipeline.
This is a simple example using AuthPlugin:
use aws_smithy_http_server::plugin::{PluginPipeline, PluginStack};
pub trait AuthPluginExt<CurrentPlugins> {
fn with_auth(self) -> PluginPipeline<PluginStack<AuthPlugin, CurrentPlugins>>;
}
impl<CurrentPlugins> AuthPluginExt<CurrentPlugins> for PluginPipeline<CurrentPlugins> {
fn with_auth(self) -> PluginPipeline<PluginStack<AuthPlugin, CurrentPlugins>> {
self.push(AuthPlugin)
}
}
let pipeline = PluginPipeline::new()
.push(LoggingPlugin)
// Our custom method!
.with_auth();Implementations§
source§impl PluginPipeline<IdentityPlugin>
impl PluginPipeline<IdentityPlugin>
sourcepub fn new() -> Self
pub fn new() -> Self
Create an empty PluginPipeline.
You can use PluginPipeline::push to add plugins to it.
source§impl<P> PluginPipeline<P>
impl<P> PluginPipeline<P>
sourcepub fn push<NewPlugin>(
self,
new_plugin: NewPlugin
) -> PluginPipeline<PluginStack<NewPlugin, P>>
pub fn push<NewPlugin>( self, new_plugin: NewPlugin ) -> PluginPipeline<PluginStack<NewPlugin, P>>
Apply a new plugin after the ones that have already been registered.
use aws_smithy_http_server::plugin::PluginPipeline;
let pipeline = PluginPipeline::new().push(LoggingPlugin).push(MetricsPlugin);The plugins’ runtime logic is executed in registration order.
In our example above, LoggingPlugin would run first, while MetricsPlugin is executed last.
Implementation notes
Plugins are applied to the underlying Operation in opposite order compared
to their registration order.
But most Plugin::map implementations desugar to appending a layer to Operation,
usually via Operation::layer.
As an example:
#[derive(Debug)]
pub struct PrintPlugin;
impl<P, Op, S, L> Plugin<P, Op, S, L> for PrintPlugin
// [...]
{
// [...]
fn map(&self, input: Operation<S, L>) -> Operation<Self::Service, Self::Layer> {
input.layer(PrintLayer { name: Op::NAME })
}
}The layer that is registered last via Operation::layer is the one that gets executed
first at runtime when a new request comes in, since it wraps the underlying service.
This is why plugins in PluginPipeline are applied in opposite order compared to their
registration order: this ensures that, at runtime, their logic is executed
in registration order.
sourcepub fn http_layer<L>(
self,
layer: L
) -> PluginPipeline<PluginStack<HttpLayer<L>, P>>
pub fn http_layer<L>( self, layer: L ) -> PluginPipeline<PluginStack<HttpLayer<L>, P>>
Applies a single [tower::Layer] to all operations before they are deserialized.
Trait Implementations§
source§impl Default for PluginPipeline<IdentityPlugin>
impl Default for PluginPipeline<IdentityPlugin>
source§impl<CurrentPlugins> InstrumentExt<CurrentPlugins> for PluginPipeline<CurrentPlugins>
impl<CurrentPlugins> InstrumentExt<CurrentPlugins> for PluginPipeline<CurrentPlugins>
source§fn instrument(
self
) -> PluginPipeline<PluginStack<InstrumentPlugin, CurrentPlugins>>
fn instrument( self ) -> PluginPipeline<PluginStack<InstrumentPlugin, CurrentPlugins>>
InstrumentLayer to all operations which respects the @sensitive trait given on the input and
output models. See InstrumentOperation for more information.