In certain situations, you may find that you require two or more middleware to function in tandem by sharing information or state. You can use [context.Context](https://golang.org/pkg/context/#Context) to pass this metadata by using [middleware.WithStackValue](https://pkg.go.dev/github.com/aws/smithy-go/middleware#WithStackValue). `middleware.WithStackValue` attaches the given key-value pair to the provided context, and safely limits the scope to the currently executing stack. These stack-scoped values can be retrieved from a context using [middleware.GetStackValue](https://pkg.go.dev/github.com/aws/smithy-go/middleware#GetStackValue) and providing the key used to stored the corresponding value. Keys must be comparable, and you must define your own types as context keys to avoid collisions. The following examples shows how two middleware can use `context.Context` to pass information down the stack.
You can pass metadata up through the stack by adding metadata key and value pairs using the [middleware.Metadata](https://pkg.go.dev/github.com/aws/smithy-go/middleware#Metadata). Each middleware step returns an output structure, metadata, and an error. Your custom middleware must return the metadata received from calling the next handler in the step. This ensures that metadata added by downstream middleware propagates to the application invoking the service operation. The resulting metadata is accessible to the invoking application by either the operation’s output shape via the `ResultMetadata` structure member.
The following examples shows how a custom middleware can add metadata that is returned as part of the operation output.