The `Router` struct has been replaced by a new `Service` located at the root of the generated crate. Its name coincides with the same name as the Smithy service you are generating.
```rust
use pokemon_service_server_sdk::PokemonService;
```
The new service builder infrastructure comes with a `Plugin` system which supports middleware on `smithy-rs`. See the [mididleware documentation](https://github.com/awslabs/smithy-rs/blob/main/design/src/server/middleware.md) and the [API documentation](https://docs.rs/aws-smithy-http-server/latest/aws_smithy_http_server/plugin/index.html) for more details.
Usage of the new service builder API:
```rust
// Apply a sequence of plugins using `PluginPipeline`.
let plugins = PluginPipeline::new()
// Apply the `PrintPlugin`.
// This is a dummy plugin found in `rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/plugin.rs`
.print()
// Apply the `InstrumentPlugin` plugin, which applies `tracing` instrumentation.
.instrument();
// Construct the service builder using the `plugins` defined above.
let app = PokemonService::builder_with_plugins(plugins)
// Assign all the handlers.
.get_pokemon_species(get_pokemon_species)
.get_storage(get_storage)
.get_server_statistics(get_server_statistics)
.capture_pokemon(capture_pokemon)
.do_nothing(do_nothing)
.check_health(check_health)
// Construct the `PokemonService`.
.build()
// If handlers are missing a descriptive error will be provided.
.expect("failed to build an instance of `PokemonService`");
```
See the `rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/bin` folder for various working examples.
### Public `FromParts` trait
Previously, we only supported one [`Extension`](https://docs.rs/aws-smithy-http-server/latest/aws_smithy_http_server/request/struct.Extension.html) as an additional argument provided to the handler. This number has been increased to 8 and the argument type has been broadened to any struct which implements the [`FromParts`](https://docs.rs/aws-smithy-http-server/latest/aws_smithy_http_server/request/trait.FromParts.html) trait. The trait is publicly exported and therefore provides customers with the ability to extend the domain of the handlers.
As noted, a ubiqutious example of a struct that implements `FromParts` is the `Extension` struct, which extracts state from the `Extensions` typemap of a [`http::Request`](https://docs.rs/http/latest/http/request/struct.Request.html). A new example is the `ConnectInfo` struct which allows handlers to access the connection data. See the `rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/bin/pokemon-service-connect-info.rs` example.
In addition to the [`ConnectInfo`](https://docs.rs/aws-smithy-http-server/latest/aws_smithy_http_server/request/connect_info/struct.ConnectInfo.html) extractor, we also have added [lambda extractors](https://docs.rs/aws-smithy-http-server/latest/aws_smithy_http_server/request/lambda/index.html) which are feature gated with `aws-lambda`.
[`FromParts` documentation](https://github.com/awslabs/smithy-rs/blob/main/design/src/server/from_parts.md) has been added.
### New Documentation
New sections to have been added to the [server side of the book](https://github.com/awslabs/smithy-rs/blob/main/design/src/server/overview.md).
- [Anatomy of a Service](https://github.com/awslabs/smithy-rs/blob/main/design/src/server/anatomy.md)
This release also introduces extensive documentation at the root of the generated crate. For best results compile documentation with `cargo +nightly doc --open`.
### Deprecations
The existing service builder infrastructure, `OperationRegistryBuilder`/`OperationRegistry`/`Router`, is now deprecated. Customers should migrate to the newer scheme described above. The deprecated types will be removed in a future release.
writer.rust("""##[deprecated(since = "0.52.0", note = "`OperationRegistry` is part of the deprecated service builder API. Use `$serviceName::builder` instead.")]""")
writer.rust("""##[deprecated(since = "0.52.0", note = "`OperationRegistryBuilder` is part of the deprecated service builder API. Use `$serviceName::builder` instead.")]""")
@@ -69,8 +70,8 @@ open class ServerServiceGenerator(
//!
//! ## Using $serviceName
//!
//! The primary entrypoint is [`$serviceName`]: it satisfies the [`Service<http::Request, Response = http::Response>`]
//! trait and therefore can be handed to a [`hyper` server] via [`$serviceName::into_make_service`] or used in Lambda via [`LambdaHandler`](#{SmithyHttpServer}::routing::LambdaHandler).
//! The primary entrypoint is [`$serviceName`]: it satisfies the [`Service<http::Request, Response = http::Response>`](#{Tower}::Service)
//! trait and therefore can be handed to a [`hyper` server](https://github.com/hyperium/hyper) via [`$serviceName::into_make_service`] or used in Lambda via [`LambdaHandler`](#{SmithyHttpServer}::routing::LambdaHandler).
@@ -236,7 +238,6 @@ open class ServerServiceGenerator(
rustCrate.lib{
documentation(this)
rust("##[doc(inline, hidden)]")
rust("pub use crate::service::{$serviceName, ${serviceName}Builder, MissingOperationsError};")
}
@@ -255,35 +256,35 @@ open class ServerServiceGenerator(
renderOperationHandler(this,operations)
}
rustCrate.withModule(
RustModule.public(
RustModule.LeafModule(
"operation_registry",
RustMetadata(
visibility=Visibility.PUBLIC,
additionalAttributes=listOf(
Attribute.Deprecated("0.52.0","This module exports the deprecated `OperationRegistry`. Use the service builder exported from your root crate."),
),
),
"""
Contains the [`operation_registry::OperationRegistry`], a place where
you can register your service's operation implementations.
## Deprecation
This service builder is deprecated - use [`${codegenContext.serviceShape.id.name.toPascalCase()}::builder_with_plugins`] or [`${codegenContext.serviceShape.id.name.toPascalCase()}::builder_without_plugins`] instead.
""",
),
){
renderOperationRegistry(this,operations)
}
// TODO(https://github.com/awslabs/smithy-rs/issues/1707): Remove, this is temporary.
/// Converts [`$serviceName`] into a [`MakeService`](tower::make::MakeService) with [`ConnectInfo`](#{SmithyHttpServer}::request::connect_info::ConnectInfo).