Source File
stack.go
Belonging Package
github.com/aws/smithy-go/middleware
package middleware
import (
)
// Stack provides protocol and transport agnostic set of middleware split into
// distinct steps. Steps have specific transitions between them, that are
// managed by the individual step.
//
// Steps are composed as middleware around the underlying handler in the
// following order:
//
// Initialize -> Serialize -> Build -> Finalize -> Deserialize -> Handler
//
// Any middleware within the chain may choose to stop and return an error or
// response. Since the middleware decorate the handler like a call stack, each
// middleware will receive the result of the next middleware in the chain.
// Middleware that does not need to react to an input, or result must forward
// along the input down the chain, or return the result back up the chain.
//
// Initialize <- Serialize -> Build -> Finalize <- Deserialize <- Handler
type Stack struct {
// Initialize prepares the input, and sets any default parameters as
// needed, (e.g. idempotency token, and presigned URLs).
//
// Takes Input Parameters, and returns result or error.
//
// Receives result or error from Serialize step.
Initialize *InitializeStep
// Serialize serializes the prepared input into a data structure that can be consumed
// by the target transport's message, (e.g. REST-JSON serialization)
//
// Converts Input Parameters into a Request, and returns the result or error.
//
// Receives result or error from Build step.
Serialize *SerializeStep
// Build adds additional metadata to the serialized transport message
// (e.g. HTTP's Content-Length header, or body checksum). Decorations and
// modifications to the message should be copied to all message attempts.
//
// Takes Request, and returns result or error.
//
// Receives result or error from Finalize step.
Build *BuildStep
// Finalize performs final preparations needed before sending the message. The
// message should already be complete by this stage, and is only alternated
// to meet the expectations of the recipient (e.g. Retry and AWS SigV4
// request signing)
//
// Takes Request, and returns result or error.
//
// Receives result or error from Deserialize step.
Finalize *FinalizeStep
// Deserialize reacts to the handler's response returned by the recipient of the request
// message. Deserializes the response into a structured type or error above
// stacks can react to.
//
// Should only forward Request to underlying handler.
//
// Takes Request, and returns result or error.
//
// Receives raw response, or error from underlying handler.
Deserialize *DeserializeStep
id string
}
// NewStack returns an initialize empty stack.
func ( string, func() interface{}) *Stack {
return &Stack{
id: ,
Initialize: NewInitializeStep(),
Serialize: NewSerializeStep(),
Build: NewBuildStep(),
Finalize: NewFinalizeStep(),
Deserialize: NewDeserializeStep(),
}
}
// ID returns the unique ID for the stack as a middleware.
func ( *Stack) () string { return .id }
// HandleMiddleware invokes the middleware stack decorating the next handler.
// Each step of stack will be invoked in order before calling the next step.
// With the next handler call last.
//
// The input value must be the input parameters of the operation being
// performed.
//
// Will return the result of the operation, or error.
func ( *Stack) ( context.Context, interface{}, Handler) (
interface{}, Metadata, error,
) {
:= DecorateHandler(,
.Initialize,
.Serialize,
.Build,
.Finalize,
.Deserialize,
)
return .Handle(, )
}
// List returns a list of all middleware in the stack by step.
func ( *Stack) () []string {
var []string
= append(, .id)
= append(, .Initialize.ID())
= append(, .Initialize.List()...)
= append(, .Serialize.ID())
= append(, .Serialize.List()...)
= append(, .Build.ID())
= append(, .Build.List()...)
= append(, .Finalize.ID())
= append(, .Finalize.List()...)
= append(, .Deserialize.ID())
= append(, .Deserialize.List()...)
return
}
func ( *Stack) () string {
var strings.Builder
:= &indentWriter{w: &}
.WriteLine(.id)
.Push()
writeStepItems(, .Initialize)
writeStepItems(, .Serialize)
writeStepItems(, .Build)
writeStepItems(, .Finalize)
writeStepItems(, .Deserialize)
return .String()
}
type stackStepper interface {
ID() string
List() []string
}
func ( *indentWriter, stackStepper) {
type interface {
() []string
}
.WriteLine(.ID())
.Push()
defer .Pop()
// ignore stack to prevent circular iterations
if , := .(*Stack); {
return
}
for , := range .List() {
.WriteLine()
}
}
type stringWriter interface {
io.Writer
WriteString(string) (int, error)
WriteRune(rune) (int, error)
}
type indentWriter struct {
w stringWriter
depth int
}
const indentDepth = "\t\t\t\t\t\t\t\t\t\t"
func ( *indentWriter) () {
.depth++
}
func ( *indentWriter) () {
.depth--
if .depth < 0 {
.depth = 0
}
}
func ( *indentWriter) ( string) {
.w.WriteString(indentDepth[:.depth])
= strings.ReplaceAll(, "\n", "\\n")
= strings.ReplaceAll(, "\r", "\\r")
.w.WriteString()
.w.WriteRune('\n')
}
The pages are generated with Golds v0.4.9. (GOOS=linux GOARCH=amd64)