Skip to content

HTTP interceptors: a better(TM) SDK request customization pipeline #2839

@lucix-aws

Description

@lucix-aws

As an SDK developer, the middleware API is a fantastic abstraction for building composable API operations.

As an SDK user, the middleware API is a fantastic abstraction for confusing yourself or otherwise breaking your application when trying to do something as simple as adding an HTTP header:

  • The interfaces are transport-agnostic, despite the fact that every single AWS service released today is over HTTP. This means that every single middleware implementation in the SDK has to implement the ubiquitous "is this an HTTP request" check that can literally never fail:
    • req, ok := in.Request.(*smithyhttp.Request) if !ok { return out, md, fmt.Errorf("this literally cannot ever happen") } 
  • Function decoration behavior of middleware is confusing and bloats / obfuscates stack traces in error logs
  • The stack construct we use for adding middleware also supports an "insert" feature where you can insert a middleware to be executed relative to another in a specific phase. But if you attempt to insert against a middleware that doesn't exist, an error is returned. This is essentially pushing a failure point that should really exist at compile time into the runtime.

We propose a new mechanism known as "Interceptors" which provides a more streamlined API for SDK users to customize request behavior.

Interceptors are transport-typed hooks which a customer can write to insert behavior at well-defined points in an operation's lifecycle. For example:

type ModifyBeforeSendInterceptor interface { ModifyBeforeSend(ctx context.Context, r *smithyhttp.Request, in any) error } // usage type attachHeader struct { h, v string } func (i attachHeader) ModifyBeforeSend(ctx context.Context, r *smithyhttp.Request, in any) error { r.Header.Set(h, v) return nil } svc := sts.NewFromConfig(cfg, func(o *sts.Options)) { o.Interceptors.ModifyBeforeSend.Add(attachHeader{"foo", "bar"}) }

To be clear, this does not replace middleware as an abstraction. It simply provides what we believe is a much more customer-friendly alternative for performing the day-to-day request manipulation that our users often require.

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature-requestA feature should be added or improved.p2This is a standard priority issuequeuedThis issues is on the AWS team's backlog

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions