Skip to content

Commit

Permalink
Various small corrections to server documentation (#2050)
Browse files Browse the repository at this point in the history
* Link to super from Handler and OperationService

* Note that structure documentation is from model

* Don't refer to ZSTs in operation_shape.rs opener

* Re-export everything from service to root

* Add reference to root documentation on service

* Fix spelling of MissingOperationsError

* #[doc(hidden)] for opaque_future

* Rename from-parts.md to from_parts.md

* Fix Connected link

* Use S type parameter and service as variable name

* Remove MissingOperation dead code

* Remove Operation header from operation.rs

* Remove reference to closures

* Document ConnectInfo<T> .0

* Add BoxBody documentation

* Rephrase operation.rs documentation

* Reference PluginPipeline from PluginStack

* Move the BoxBody documentation

* Document Plugin associated types

* Add example implementation for Plugin

* Link to plugin module from Plugin

* Improve FromParts/FromRequest documentation

* Remove links to doc(hidden) RuntimeError

* Add link from Upgradable to operation module
  • Loading branch information
hlbarber authored Dec 2, 2022
1 parent ee6242c commit 5073a25
Show file tree
Hide file tree
Showing 23 changed files with 141 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ sealed class RustModule {

/* Common modules used across client, server and tests */
val Config = public("config", documentation = "Configuration for the service.")
val Error = public("error", documentation = "All error types that operations can return.")
val Model = public("model", documentation = "Data structures used by operation inputs/outputs.")
val Input = public("input", documentation = "Input structures for operations.")
val Output = public("output", documentation = "Output structures for operations.")
val Error = public("error", documentation = "All error types that operations can return. Documentation on these types is copied from the model.")
val Model = public("model", documentation = "Data structures used by operation inputs/outputs. Documentation on these types is copied from the model.")
val Input = public("input", documentation = "Input structures for operations. Documentation on these types is copied from the model.")
val Output = public("output", documentation = "Output structures for operations. Documentation on these types is copied from the model.")
val Types = public("types", documentation = "Data primitives referenced by other data types.")

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ open class RustCrate(
}
}

val ErrorsModule = RustModule.public("error", documentation = "All error types that operations can return.")
val ErrorsModule = RustModule.public("error", documentation = "All error types that operations can return. Documentation on these types is copied from the model.")
val OperationsModule = RustModule.public("operation", documentation = "All operations that this crate can perform.")
val ModelsModule = RustModule.public("model", documentation = "Data structures used by operation inputs/outputs.")
val InputsModule = RustModule.public("input", documentation = "Input structures for operations.")
val OutputsModule = RustModule.public("output", documentation = "Output structures for operations.")
val ModelsModule = RustModule.public("model", documentation = "Data structures used by operation inputs/outputs. Documentation on these types is copied from the model.")
val InputsModule = RustModule.public("input", documentation = "Input structures for operations. Documentation on these types is copied from the model.")
val OutputsModule = RustModule.public("output", documentation = "Output structures for operations. Documentation on these types is copied from the model.")

val UnconstrainedModule =
RustModule.private("unconstrained", "Unconstrained types for constrained shapes.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ServerOperationShapeGenerator(

writer.rustTemplate(
"""
//! A collection of zero-sized types (ZSTs) representing each operation defined in the service closure.
//! A collection of types representing each operation defined in the service closure.
//!
//! ## Constructing an [`Operation`](#{SmithyHttpServer}::operation::OperationShapeExt)
//!
Expand All @@ -54,8 +54,9 @@ class ServerOperationShapeGenerator(
//!
//! ## Use as Marker Structs
//!
//! The [plugin system](#{SmithyHttpServer}::plugin) also makes use of these ZSTs to parameterize
//! [`Plugin`](#{SmithyHttpServer}::plugin::Plugin) implementations. The traits, such as
//! The [plugin system](#{SmithyHttpServer}::plugin) also makes use of these
//! [zero-sized types](https://doc.rust-lang.org/nomicon/exotic-sizes.html##zero-sized-types-zsts) (ZSTs) to
//! parameterize [`Plugin`](#{SmithyHttpServer}::plugin::Plugin) implementations. The traits, such as
//! [`OperationShape`](#{SmithyHttpServer}::operation::OperationShape) can be used to provide
//! operation specific information to the [`Layer`](#{Tower}::Layer) being applied.
""".trimIndent(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ open class ServerServiceGenerator(
fun render() {
rustCrate.lib {
rust("##[doc(inline, hidden)]")
rust("pub use crate::service::$serviceName;")
rust("pub use crate::service::{$serviceName, ${serviceName}Builder, MissingOperationsError};")
}

rustCrate.withModule(RustModule.operation(Visibility.PRIVATE)) {
Expand Down Expand Up @@ -90,7 +90,7 @@ open class ServerServiceGenerator(

// TODO(https://github.com/awslabs/smithy-rs/issues/1707): Remove, this is temporary.
rustCrate.withModule(
RustModule.LeafModule("service", RustMetadata(visibility = Visibility.PUBLIC, additionalAttributes = listOf(Attribute.DocHidden)), null),
RustModule.LeafModule("service", RustMetadata(visibility = Visibility.PRIVATE, additionalAttributes = listOf(Attribute.DocHidden)), null),
) {
ServerServiceGeneratorV2(
codegenContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ class ServerServiceGeneratorV2(

rustTemplate(
"""
///
/// See the [root](crate) documentation for more information.
##[derive(Clone)]
pub struct $serviceName<S = #{SmithyHttpServer}::routing::Route> {
router: #{SmithyHttpServer}::routers::RoutingService<#{Router}<S>, #{Protocol}>,
Expand Down Expand Up @@ -569,11 +571,11 @@ class ServerServiceGeneratorV2(
///
/// #### Build
///
/// You can convert [`$builderName`] into [`$serviceName`] using either [`$builderName::build`] or [`$builderName::build_unchecked`].
/// You can convert [`$builderName`] into [`$serviceName`] using either [`$builderName::build`] or [`$builderName::build_unchecked`].
///
/// [`$builderName::build`] requires you to provide a handler for every single operation in your Smithy model. It will return an error if that is not the case.
/// [`$builderName::build`] requires you to provide a handler for every single operation in your Smithy model. It will return an error if that is not the case.
///
/// [`$builderName::build_unchecked`], instead, does not require exhaustiveness. The server will automatically return 500s to all requests for operations that do not have a registered handler.
/// [`$builderName::build_unchecked`], instead, does not require exhaustiveness. The server will automatically return 500s to all requests for operations that do not have a registered handler.
/// [`$builderName::build_unchecked`] is particularly useful if you are deploying your Smithy service as a collection of Lambda functions, where each Lambda is only responsible for a subset of the operations in the Smithy service (or even a single one!).
///
/// ## Example
Expand Down
2 changes: 1 addition & 1 deletion design/src/rfcs/rfc0024_request_id.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ RequestIDs are not to be used by multiple services, but only within a single ser
The user experience if this RFC is implemented
----------------------------------------------

The proposal is to implement a `RequestId` type and make it available to middleware and business logic handlers, through [FromParts](../server/from-parts.md) and as a `Service`.
The proposal is to implement a `RequestId` type and make it available to middleware and business logic handlers, through [FromParts](../server/from_parts.md) and as a `Service`.
To aid customers already relying on clients' request IDs, there will be two types: `ClientRequestId` and `ServerRequestId`.

1. Implementing `FromParts` for `Extension<RequestId>` gives customers the ability to write their handlers:
Expand Down
1 change: 1 addition & 0 deletions design/src/server/anatomy.md
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ use http::request::Parts;
/// Provides a protocol aware extraction from a [`Request`]. This borrows the
/// [`Parts`], in contrast to [`FromRequest`].
pub trait FromParts<Protocol>: Sized {
/// The type of the failures yielded extraction attempts.
type Rejection: IntoResponse<Protocol>;

/// Extracts `self` from a [`Parts`] synchronously.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ But what if we, the customer, want to access data in the handler which is _not_
/// Provides a protocol aware extraction from a [`Request`]. This borrows the
/// [`Parts`], in contrast to [`FromRequest`].
pub trait FromParts<Protocol>: Sized {
/// The type of the failures yielded extraction attempts.
type Rejection: IntoResponse<Protocol>;

/// Extracts `self` from a [`Parts`] synchronously.
Expand Down
2 changes: 1 addition & 1 deletion design/src/server/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ Smithy Rust provides the ability to generate a server whose operations are provi
<!-- - [Middleware](./middleware.md) -->
- [Instrumentation](./instrumentation.md)
<!-- - [The Anatomy of a Service](./anatomy.md) -->
<!-- - [Accessing Un-modelled Data](./from-parts.md) -->
<!-- - [Accessing Un-modelled Data](./from_parts.md) -->
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ async fn plugin_layers_are_executed_in_registration_order() {
let pipeline = PluginPipeline::new()
.push(SentinelPlugin::new("first", output.clone()))
.push(SentinelPlugin::new("second", output.clone()));
let mut app = pokemon_service_server_sdk::service::PokemonService::builder_with_plugins(pipeline)
let mut app = pokemon_service_server_sdk::PokemonService::builder_with_plugins(pipeline)
.do_nothing(do_nothing)
.build_unchecked();
let request = DoNothingInput::builder()
Expand Down
1 change: 1 addition & 0 deletions rust-runtime/aws-smithy-http-server/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use bytes::Bytes;

use crate::error::{BoxError, Error};

/// The primary [`Body`] returned by the generated `smithy-rs` service.
pub type BoxBody = http_body::combinators::UnsyncBoxBody<Bytes, Error>;

// `boxed` is used in the codegen of the implementation of the operation `Handler` trait.
Expand Down
3 changes: 1 addition & 2 deletions rust-runtime/aws-smithy-http-server/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ impl Deref for ModeledErrorExtension {
}
}

/// Extension type used to store the _name_ of the [`crate::runtime_error::RuntimeError`] that
/// occurred during request handling (see [`crate::runtime_error::RuntimeError::name`]).
/// Extension type used to store the _name_ of the possible runtime errors.
/// These are _unmodeled_ errors; the operation handler was not invoked.
#[derive(Debug, Clone)]
pub struct RuntimeErrorExtension(String);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! # Ok(Response::new(()))
//! # }
//! # async fn example() {
//! # let svc = service_fn(service);
//! # let service = service_fn(service);
//! let request = Request::get("http://localhost/a/b/c/d?bar=hidden")
//! .header("header-name-a", "hidden")
//! .body(())
Expand Down Expand Up @@ -47,11 +47,11 @@
//! }
//! })
//! .status_code();
//! let mut svc = InstrumentOperation::new(svc, "foo-operation")
//! let mut service = InstrumentOperation::new(service, "foo-operation")
//! .request_fmt(request_fmt)
//! .response_fmt(response_fmt);
//!
//! let _ = svc.call(request).await.unwrap();
//! let _ = service.call(request).await.unwrap();
//! # }
//! ```
//!
Expand Down
26 changes: 13 additions & 13 deletions rust-runtime/aws-smithy-http-server/src/instrumentation/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,16 @@ where
/// # svc.call(Request::new(()));
/// ```
#[derive(Debug, Clone)]
pub struct InstrumentOperation<Svc, RequestMakeFmt = MakeIdentity, ResponseMakeFmt = MakeIdentity> {
inner: Svc,
pub struct InstrumentOperation<S, RequestMakeFmt = MakeIdentity, ResponseMakeFmt = MakeIdentity> {
inner: S,
operation_name: &'static str,
make_request: RequestMakeFmt,
make_response: ResponseMakeFmt,
}

impl<Svc> InstrumentOperation<Svc> {
impl<S> InstrumentOperation<S> {
/// Constructs a new [`InstrumentOperation`] with no data redacted.
pub fn new(inner: Svc, operation_name: &'static str) -> Self {
pub fn new(inner: S, operation_name: &'static str) -> Self {
Self {
inner,
operation_name,
Expand All @@ -120,11 +120,11 @@ impl<Svc> InstrumentOperation<Svc> {
}
}

impl<Svc, RequestMakeFmt, ResponseMakeFmt> InstrumentOperation<Svc, RequestMakeFmt, ResponseMakeFmt> {
impl<S, RequestMakeFmt, ResponseMakeFmt> InstrumentOperation<S, RequestMakeFmt, ResponseMakeFmt> {
/// Configures the request format.
///
/// The argument is typically [`RequestFmt`](super::sensitivity::RequestFmt).
pub fn request_fmt<R>(self, make_request: R) -> InstrumentOperation<Svc, R, ResponseMakeFmt> {
pub fn request_fmt<R>(self, make_request: R) -> InstrumentOperation<S, R, ResponseMakeFmt> {
InstrumentOperation {
inner: self.inner,
operation_name: self.operation_name,
Expand All @@ -136,7 +136,7 @@ impl<Svc, RequestMakeFmt, ResponseMakeFmt> InstrumentOperation<Svc, RequestMakeF
/// Configures the response format.
///
/// The argument is typically [`ResponseFmt`](super::sensitivity::ResponseFmt).
pub fn response_fmt<R>(self, make_response: R) -> InstrumentOperation<Svc, RequestMakeFmt, R> {
pub fn response_fmt<R>(self, make_response: R) -> InstrumentOperation<S, RequestMakeFmt, R> {
InstrumentOperation {
inner: self.inner,
operation_name: self.operation_name,
Expand All @@ -146,10 +146,10 @@ impl<Svc, RequestMakeFmt, ResponseMakeFmt> InstrumentOperation<Svc, RequestMakeF
}
}

impl<Svc, U, V, RequestMakeFmt, ResponseMakeFmt> Service<Request<U>>
for InstrumentOperation<Svc, RequestMakeFmt, ResponseMakeFmt>
impl<S, U, V, RequestMakeFmt, ResponseMakeFmt> Service<Request<U>>
for InstrumentOperation<S, RequestMakeFmt, ResponseMakeFmt>
where
Svc: Service<Request<U>, Response = Response<V>>,
S: Service<Request<U>, Response = Response<V>>,

for<'a> RequestMakeFmt: MakeDebug<&'a HeaderMap>,
for<'a> RequestMakeFmt: MakeDisplay<&'a Uri>,
Expand All @@ -158,9 +158,9 @@ where
for<'a> ResponseMakeFmt: MakeDebug<&'a HeaderMap>,
for<'a> ResponseMakeFmt: MakeDisplay<StatusCode>,
{
type Response = Svc::Response;
type Error = Svc::Error;
type Future = InstrumentedFuture<Svc::Future, ResponseMakeFmt>;
type Response = S::Response;
type Error = S::Error;
type Future = InstrumentedFuture<S::Future, ResponseMakeFmt>;

fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
Expand Down
1 change: 1 addition & 0 deletions rust-runtime/aws-smithy-http-server/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
//! Macros implementation.
/// Define a type that implements [`std::future::Future`].
#[doc(hidden)]
#[macro_export]
macro_rules! opaque_future {
($(#[$m:meta])* pub type $name:ident = $actual:ty;) => {
Expand Down
2 changes: 2 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/operation/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use tower::Service;
use super::{OperationError, OperationShape};

/// A utility trait used to provide an even interface for all operation handlers.
///
/// See [`operation`](crate::operation) documentation for more info.
pub trait Handler<Op, Exts>
where
Op: OperationShape,
Expand Down
10 changes: 4 additions & 6 deletions rust-runtime/aws-smithy-http-server/src/operation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

//! # Operations.
//!
//! The shape of a [Smithy operation] is modelled by the [`OperationShape`] trait. Its associated types
//! [`OperationShape::Input`], [`OperationShape::Output`], and [`OperationShape::Error`] map to the structures
//! representing the Smithy inputs, outputs, and errors respectively. When an operation error is not specified
//! [`OperationShape::Error`] is [`Infallible`](std::convert::Infallible).
//!
//! We should generate a zero-sized type (ZST) for each Smithy operation and [`OperationShape`] should be implemented
//! on it. This will be used as a helper - providing static methods and parameterizing other traits.
//! We generate a marker struct for each Smithy operation and implement [`OperationShape`] on them. This
//! is used as a helper - providing static methods and parameterizing other traits.
//!
//! The model
//!
Expand Down Expand Up @@ -41,7 +39,7 @@
//! }
//! ```
//!
//! The behavior of a Smithy operation is encoded by an [`Operation`]. The [`OperationShape`] ZSTs can be used to
//! The behavior of a Smithy operation is encoded by an [`Operation`]. The [`OperationShape`] types can be used to
//! construct specific operations using [`OperationShapeExt::from_handler`] and [`OperationShapeExt::from_service`].
//! The [from_handler](OperationShapeExt::from_handler) constructor takes a [`Handler`] whereas the
//! [from_service](OperationShapeExt::from_service) takes a [`OperationService`]. Both traits serve a similar purpose -
Expand All @@ -52,7 +50,7 @@
//! The [`Handler`] trait is implemented by all async functions which accept [`OperationShape::Input`] as their first
//! argument, the remaining arguments implement [`FromParts`](crate::request::FromParts), and return either
//! [`OperationShape::Output`] when [`OperationShape::Error`] is [`Infallible`](std::convert::Infallible) or
//! [`Result`]<[`OperationShape::Output`],[`OperationShape::Error`]>. The following are examples of closures which
//! [`Result`]<[`OperationShape::Output`],[`OperationShape::Error`]>. The following are examples of async functions which
//! implement [`Handler`]:
//!
//! ```rust,no_run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use super::{OperationError, OperationShape};
/// This serves to take [`Service`]s of the form `Service<(Op::Input, Ext0, Ext1, ...)>` to the canonical
/// representation of `Service<(Input, (Ext0, Ext1, ...))>` inline with
/// [`IntoService`](super::IntoService).
///
/// See [`operation`](crate::operation) documentation for more info.
pub trait OperationService<Op, Exts, PollError>:
Service<Self::Normalized, Response = Op::Output, Error = OperationError<Op::Error, PollError>>
where
Expand Down
7 changes: 2 additions & 5 deletions rust-runtime/aws-smithy-http-server/src/operation/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ where
}

/// An interface to convert a representation of a Smithy operation into a [`Route`].
///
/// See the [module](crate::operation) documentation for more information.
pub trait Upgradable<Protocol, Operation, Exts, B, Plugin> {
/// Upgrade the representation of a Smithy operation to a [`Route`].
fn upgrade(self, plugin: &Plugin) -> Route<B>;
Expand Down Expand Up @@ -271,11 +273,6 @@ where
}
}

/// A marker struct indicating an [`Operation`] has not been set in a builder.
///
/// This does _not_ implement [`Upgradable`] purposely.
pub struct MissingOperation;

/// A marker struct indicating an [`Operation`] has not been set in a builder.
///
/// This _does_ implement [`Upgradable`] but produces a [`Service`] which always returns an internal failure message.
Expand Down
Loading

0 comments on commit 5073a25

Please sign in to comment.