diff --git a/README.md b/README.md index e4963e3..661927e 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,26 @@ Outer layers {customer} ## Proposal +The trait `OperationShape` models Smithy operations. + +```rust +trait OperationShape { + type Input; + type Output; + type Error; +} +``` + +A service builder sets an operation by accepting `Operation` where `S: Service<(Op::Input, Exts), Response = Op::Output, Error = PollError | Op::Error>>`, `OperationInput: FromRequest`, `Exts: FromRequest`, `Op::Output: IntoResponse`, and `Op::Error: IntoResponse` for `Op: OperationShape`. + +To construct a `Operation` there are two constructors, `from_handler` which accepts a `H: Handler` and `from_service` which accepts a `S: Flattened`. The trait `Handler` is enjoyed by all closures which accept `(Op::Input, ...)` and return `Result`. The trait `Flattened` is enjoyed by all `Service<(Op::Input, ...), Response = Op::Output, Error = PollError | Op::Error>`. Both `Handler` and `Flattened` work to provide a common interface to convert to `S: Service<(Op::Input, Exts), Response = Op::Output, Error = PollError | Op::Error>` in `Operation`. + +The `UpgradeLayer` is a `Layer` applied to such `S` which uses the `FromRequest` and `IntoResponse` to provide middleware taking `S: Service<(Op::Input, Exts), Response = Op::Output, Error = PollError | Op::Error>` to `S: Service` in a protocol and operation aware way. + +The `Operation::upgrade` takes `S`, applies `UpgradeLayer`, then applies the `L: Layer`. The `L` in `Operation` can be set by the user to provide operation specific HTTP middleware. The `Operation::upgrade` is called in the service builder `build` method and the composition is immediately `Box`'d and collected up into the protocol specific router alongside the other routes. + +In this way the customer can provide, for a specific operation, middleware around `S` _and_ `S` after it's upgraded to a HTTP service via `L`. + ``` Outer layers {customer} |- Router {runtime + codegen}