Allow server decorators to inject methods on config (#3111)
PR #3095 added a code-generated `${serviceName}Config` object on which
users can register layers and plugins. For example:
```rust
let config = PokemonServiceConfig::builder()
.layer(layers)
.http_plugin(authn_plugin)
.model_plugin(authz_plugin)
.build();
```
This PR makes it so that server decorators can inject methods on this
config builder object. These methods can apply arbitrary layers, HTTP
plugins, and/or model plugins. Moreover, the decorator can configure
whether invoking such method is required or not.
For example, a decorator can inject an `aws_auth` method that configures
some plugins using its input arguments. Missing invocation of this
method
will result in the config failing to build:
```rust
let _: SimpleServiceConfig<
// No layers have been applied.
tower::layer::util::Identity,
// One HTTP plugin has been applied.
PluginStack<IdentityPlugin, IdentityPlugin>,
// One model plugin has been applied.
PluginStack<IdentityPlugin, IdentityPlugin>,
> = SimpleServiceConfig::builder()
// This method has been injected in the config builder!
.aws_auth("a".repeat(69).to_owned(), 69)
// The method will apply one HTTP plugin and one model plugin,
// configuring them with the input arguments. Configuration can be
// declared to be fallible, in which case we get a `Result` we unwrap
// here.
.expect("failed to configure aws_auth")
.build()
// Since `aws_auth` has been marked as required, if the user misses
// invoking it, this would panic here.
.unwrap();
```
----
_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
Loading
Please sign in to comment