diff --git a/content/en/docs/faq/_index.md b/content/en/docs/faq/_index.md new file mode 100644 index 00000000000..8d057b49bb7 --- /dev/null +++ b/content/en/docs/faq/_index.md @@ -0,0 +1,97 @@ +--- +title: "Frequently Asked Questions" +linkTitle: "FAQ / Troubleshooting" +description: "Answers to some commonly-asked questions about the {{% alias sdk-go %}}" +weight: 9 +--- + +### How do I configure my SDK's HTTP client? Are there any guidelines or best practices? + +We are unable to provide guidance to customers on how to configure their HTTP +workflow in a manner that is most effective for their particular workload. The +answer to this is the product of a multivariate equation, with input factors +including but not limited to: + +* the network footprint of the application (TPS, throughput, etc.) +* the services being used +* the compute characteristics of the deployment +* the geographical nature of the deployment +* the desired application behavior or needs of the application itself (SLAs, + timings, etc.) + +### How should I configure operation timeouts? + +Much like the previous question, it depends. Elements to consider here include +the following: + +* All of the above factors concerning HTTP client config +* Your own application timing or SLA constraints (e.g. if you yourself serve + traffic to other consumers) + +**The answer to this question should almost NEVER be based on pure empirical +observation of upstream behavior** - e.g. "I made 1000 calls to this operation, +it took at most 5 seconds so I will set the timeout based on that with a safety +factor of 2x to 10 seconds". Environment conditions can change, services can +temporarily degrade, and these types of assumptions can become wrong without +warning. + +### Requests made by the SDK are timing out or taking too long, how do I fix this? + +We are unable to assist with extended or timed-out operation calls due to +extended time spent on the wire. "Wire time" in the SDK is defined as any of +the following: +* Time spent in an SDK client's `HTTPClient.Do()` method +* Time spent in `Read()`s on an HTTP response body that has been forwarded to + the caller (e.g. `GetObject`) + +If you are experiencing issues due to operation latency or timeouts, your first +course of action should be to obtain telemetry of the SDK operation lifecycle +to determine the timing breakdown between time spent on the wire and the +surrounding overhead of the operation. See the guide on +[timing SDK operations]({{< ref "/docs/faq/timing-operations.md" >}}), +which contains a reusable code snippet that can achieve this. + +### How do I fix a `read: connection reset` error? + +The SDK retries any errors matching the `connection reset` pattern by default. +This will cover error handling for most operations, where the operation's HTTP +response is fully consumed and deserialized into its modeled result type. + +However, this error can still occur in a context **outside** of the retry loop: +certain service operations directly forward the API's HTTP response body to the +caller to be consumed from the wire directly via `io.ReadCloser` (e.g. +`GetObject`'s object payload). You may encounter this error when performing a +`Read` on the response body. + +This error indicates that your host, the service or any intermediary party +(e.g. NAT gateways, proxies, load balancers) closed the connection while +attempting to read the response. + +This can occur for several reasons: +* You did not consume the response body for some time after the response itself + was received (after the service operation was called). **We recommend you + consume the HTTP response body as soon as possible for these types of + operations.** +* You did not close a previously-received response body. This can cause + connection resets on certain platforms. **You MUST close any `io.ReadCloser` + instances provided in an operation's response, regardless of whether you + consume its contents.** + +Beyond that, try running a tcpdump for an affected connection at the edge of +your network (e.g. after any proxies that you control). If you see that the AWS +endpoint seems to be sending a TCP RST, you should use the AWS support console +to open a case against the offending service. Be prepared to provide request +IDs and specific timestamps of when the issue occured. + +### Why am I getting "invalid signature" errors when using an HTTP proxy with the SDK? + +The signature algorithm for AWS services (generally sigv4) is tied to the +serialized request's headers, more specifically most headers prefixed with +`X-`. Proxies are prone to modifying the outgoing request by adding additional +forwarding information (often via an `X-Forwarded-For` header) which +effectively breaks the signature that the SDK calculated. + +If you're using an HTTP proxy and experiencing signature errors, you should +work to capture the request **as it appears outgoing from the proxy** and +determine whether it is different. + diff --git a/content/en/docs/faq/timing-operations.md b/content/en/docs/faq/timing-operations.md new file mode 100644 index 00000000000..5e1d4e2dbb0 --- /dev/null +++ b/content/en/docs/faq/timing-operations.md @@ -0,0 +1,250 @@ +--- +title: "Timing SDK operations" +linkTitle: "Timing Operations" +description: "How to perform basic instrumentation in the {{% alias sdk-go %}} to time SDK operations" +weight: 1 +--- + +When debugging timeout / latency issues in the SDK, it is critical to identify +the components of the operation lifecycle which are taking more time to execute +than expected. As a starting point, you will generally need to inspect the +timing breakdown between the overall operation call and the HTTP call itself. + +The following sample program implements a basic instrumentation probe in terms +of `smithy-go` middleware for SQS clients and demonstrates how it is used. The +probe emits the following information for each operation call: + +* AWS request ID +* service ID +* operation name +* operation invocation time +* http call time + +Each emitted message is prefixed with a unique (to a single operation) +"invocation ID" which is set at the beginning of the handler stack. + +The entry point for instrumentation is exposed as `WithOperationTiming`, which +is parameterized to accept a message handling function which will receive +instrumentation "events" as formatted strings. `PrintfMSGHandler` is provided +as a convenience which will simply dump messages to stdout. + +The service used here is interchangeable - ALL service client options accept +`APIOptions` and an `HTTPClient` as configuration. For example, +`WithOperationTiming` could instead be declared as: + +```go +func WithOperationTiming(msgHandler func(string)) func(*s3.Options) +func WithOperationTiming(msgHandler func(string)) func(*dynamodb.Options) +// etc. +``` + +If you change it, be sure to change the signature of the function it returns as +well. + +```go +import ( + "context" + "fmt" + "log" + "net/http" + "sync" + "time" + + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sqs" + "github.com/aws/smithy-go/middleware" + smithyrand "github.com/aws/smithy-go/rand" +) + +// WithOperationTiming instruments an SQS client to dump timing information for +// the following spans: +// - overall operation time +// - HTTPClient call time +// +// This instrumentation will also emit the request ID, service name, and +// operation name for each invocation. +// +// Accepts a message "handler" which is invoked with formatted messages to be +// handled externally, you can use the declared PrintfMSGHandler to simply dump +// these values to stdout. +func WithOperationTiming(msgHandler func(string)) func(*sqs.Options) { + return func(o *sqs.Options) { + o.APIOptions = append(o.APIOptions, addTimingMiddlewares(msgHandler)) + o.HTTPClient = &timedHTTPClient{ + client: awshttp.NewBuildableClient(), + msgHandler: msgHandler, + } + } +} + +// PrintfMSGHandler writes messages to stdout. +func PrintfMSGHandler(msg string) { + fmt.Printf("%s\n", msg) +} + +type invokeIDKey struct{} + +func setInvokeID(ctx context.Context, id string) context.Context { + return middleware.WithStackValue(ctx, invokeIDKey{}, id) +} + +func getInvokeID(ctx context.Context) string { + id, _ := middleware.GetStackValue(ctx, invokeIDKey{}).(string) + return id +} + +// Records the current time, and returns a function to be called when the +// target span of events is completed. The return function will emit the given +// span name and time elapsed to the given message consumer. +func timeSpan(ctx context.Context, name string, consumer func(string)) func() { + start := time.Now() + return func() { + elapsed := time.Now().Sub(start) + consumer(fmt.Sprintf("[%s] %s: %s", getInvokeID(ctx), name, elapsed)) + } +} + +type timedHTTPClient struct { + client *awshttp.BuildableClient + msgHandler func(string) +} + +func (c *timedHTTPClient) Do(r *http.Request) (*http.Response, error) { + defer timeSpan(r.Context(), "http", c.msgHandler)() + + resp, err := c.client.Do(r) + if err != nil { + return nil, fmt.Errorf("inner client do: %v", err) + } + + return resp, nil +} + +type addInvokeIDMiddleware struct { + msgHandler func(string) +} + +func (*addInvokeIDMiddleware) ID() string { return "addInvokeID" } + +func (*addInvokeIDMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, md middleware.Metadata, err error, +) { + id, err := smithyrand.NewUUID(smithyrand.Reader).GetUUID() + if err != nil { + return out, md, fmt.Errorf("new uuid: %v", err) + } + + return next.HandleInitialize(setInvokeID(ctx, id), in) +} + +type timeOperationMiddleware struct { + msgHandler func(string) +} + +func (*timeOperationMiddleware) ID() string { return "timeOperation" } + +func (m *timeOperationMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + middleware.InitializeOutput, middleware.Metadata, error, +) { + defer timeSpan(ctx, "operation", m.msgHandler)() + return next.HandleInitialize(ctx, in) +} + +type emitMetadataMiddleware struct { + msgHandler func(string) +} + +func (*emitMetadataMiddleware) ID() string { return "emitMetadata" } + +func (m *emitMetadataMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + middleware.InitializeOutput, middleware.Metadata, error, +) { + out, md, err := next.HandleInitialize(ctx, in) + + invokeID := getInvokeID(ctx) + requestID, _ := awsmiddleware.GetRequestIDMetadata(md) + service := awsmiddleware.GetServiceID(ctx) + operation := awsmiddleware.GetOperationName(ctx) + m.msgHandler(fmt.Sprintf(`[%s] requestID = "%s"`, invokeID, requestID)) + m.msgHandler(fmt.Sprintf(`[%s] service = "%s"`, invokeID, service)) + m.msgHandler(fmt.Sprintf(`[%s] operation = "%s"`, invokeID, operation)) + + return out, md, err +} + +func addTimingMiddlewares(mh func(string)) func(*middleware.Stack) error { + return func(s *middleware.Stack) error { + if err := s.Initialize.Add(&timeOperationMiddleware{msgHandler: mh}, middleware.Before); err != nil { + return fmt.Errorf("add time operation middleware: %v", err) + } + if err := s.Initialize.Add(&addInvokeIDMiddleware{msgHandler: mh}, middleware.Before); err != nil { + return fmt.Errorf("add invoke id middleware: %v", err) + } + if err := s.Initialize.Insert(&emitMetadataMiddleware{msgHandler: mh}, "RegisterServiceMetadata", middleware.After); err != nil { + return fmt.Errorf("add emit metadata middleware: %v", err) + } + return nil + } +} + +func main() { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + log.Fatal(fmt.Errorf("load default config: %v", err)) + } + + svc := sqs.NewFromConfig(cfg, WithOperationTiming(PrintfMSGHandler)) + + var wg sync.WaitGroup + + for i := 0; i < 6; i++ { + wg.Add(1) + go func() { + defer wg.Done() + + _, err = svc.ListQueues(context.Background(), nil) + if err != nil { + fmt.Println(fmt.Errorf("list queues: %v", err)) + } + }() + } + wg.Wait() +} +``` + +A sample output of this program: + +``` +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] http: 192.24067ms +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] requestID = "dbee3082-96a3-5b23-adca-6d005696fa94" +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] service = "SQS" +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] operation = "ListQueues" +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] operation: 193.098393ms +[0740f0e0-953e-4328-94fc-830a5052e763] http: 195.185732ms +[0740f0e0-953e-4328-94fc-830a5052e763] requestID = "48b301fa-fc9f-5f1f-9007-5c783caa9322" +[0740f0e0-953e-4328-94fc-830a5052e763] service = "SQS" +[0740f0e0-953e-4328-94fc-830a5052e763] operation = "ListQueues" +[0740f0e0-953e-4328-94fc-830a5052e763] operation: 195.725491ms +[c0589832-f351-4cc7-84f1-c656eb79dbd7] http: 200.52383ms +[444030d0-6743-4de5-bd91-bc40b2b94c55] http: 200.525919ms +[c0589832-f351-4cc7-84f1-c656eb79dbd7] requestID = "4a73cc82-b47b-56e1-b327-9100744e1b1f" +[c0589832-f351-4cc7-84f1-c656eb79dbd7] service = "SQS" +[c0589832-f351-4cc7-84f1-c656eb79dbd7] operation = "ListQueues" +[c0589832-f351-4cc7-84f1-c656eb79dbd7] operation: 201.214365ms +[444030d0-6743-4de5-bd91-bc40b2b94c55] requestID = "ca1523ed-1879-5610-bf5d-7e6fd84cabee" +[444030d0-6743-4de5-bd91-bc40b2b94c55] service = "SQS" +[444030d0-6743-4de5-bd91-bc40b2b94c55] operation = "ListQueues" +[444030d0-6743-4de5-bd91-bc40b2b94c55] operation: 201.197071ms +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] http: 206.449568ms +[12b2b39d-df86-4648-a436-ff0482d13340] http: 206.526603ms +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] requestID = "64229710-b552-56ed-8f96-ca927567ec7b" +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] service = "SQS" +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] operation = "ListQueues" +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] operation: 207.252357ms +[12b2b39d-df86-4648-a436-ff0482d13340] requestID = "76d9cbc0-07aa-58aa-98b7-9642c79f9851" +[12b2b39d-df86-4648-a436-ff0482d13340] service = "SQS" +[12b2b39d-df86-4648-a436-ff0482d13340] operation = "ListQueues" +[12b2b39d-df86-4648-a436-ff0482d13340] operation: 207.360621ms +``` diff --git a/content/en/docs/making-requests.md b/content/en/docs/making-requests.md index 9fd244d95f8..93fe1245f91 100644 --- a/content/en/docs/making-requests.md +++ b/content/en/docs/making-requests.md @@ -233,14 +233,21 @@ if err != nil { For more information on error handling, including how to inspect for specific error types, see the [Handling Errors]({{% ref "handling-errors.md" %}}) documentation. -#### Responses with io.ReadCloser +#### Responses with `io.ReadCloser` -Some API operations return a response struct that contain an output member that is an `io.ReadCloser`. If you're making -requests with these operations, always be sure to call `io.ReadCloser` member's `Close` method after you've completed -reading the content. +Some API operations return a response struct that contain an output member that +is an `io.ReadCloser`. This will be the case for API operations that expose +some element of their output in the body of the HTTP response itself. -For example {{% alias service=S3 %}} `GetObject` operation returns a response -whose `Body` member is an `io.ReadCloser`: +For example, {{% alias service=S3 %}} `GetObject` operation returns a response +whose `Body` member is an `io.ReadCloser` for accessing the object payload. + +{{% pageinfo color="warning" %}} +**You MUST ALWAYS `Close()` any `io.ReadCloser` output members, regardless of +whether you've consumed its content. Failure to do so can leak resources and +potentially create issues with reading response bodies for operations called in +the future.** +{{% /pageinfo %}} ```go resp, err := s3svc.GetObject(context.TODO(), &s3.GetObjectInput{...}) diff --git a/docs/404.html b/docs/404.html index 722c7cda3ac..7aa2859227b 100644 --- a/docs/404.html +++ b/docs/404.html @@ -99,7 +99,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/docs/cloud9-go/index.html b/docs/docs/cloud9-go/index.html index 825fc7959e4..e05c171ecba 100644 --- a/docs/docs/cloud9-go/index.html +++ b/docs/docs/cloud9-go/index.html @@ -105,7 +105,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -127,7 +127,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -145,7 +145,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/cloudwatch/index.html b/docs/docs/code-examples/cloudwatch/index.html index 4f927be8648..0f1051878c6 100644 --- a/docs/docs/code-examples/cloudwatch/index.html +++ b/docs/docs/code-examples/cloudwatch/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/dynamodb/index.html b/docs/docs/code-examples/dynamodb/index.html index 31017634d24..0fb2b369bcd 100644 --- a/docs/docs/code-examples/dynamodb/index.html +++ b/docs/docs/code-examples/dynamodb/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/ec2/index.html b/docs/docs/code-examples/ec2/index.html index 57e3bfeec5d..6f359516ff0 100644 --- a/docs/docs/code-examples/ec2/index.html +++ b/docs/docs/code-examples/ec2/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/iam/index.html b/docs/docs/code-examples/iam/index.html index 71472dda5e7..5bb998b7d29 100644 --- a/docs/docs/code-examples/iam/index.html +++ b/docs/docs/code-examples/iam/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/index.html b/docs/docs/code-examples/index.html index 0fe285064a6..1539ba60682 100644 --- a/docs/docs/code-examples/index.html +++ b/docs/docs/code-examples/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/kms/index.html b/docs/docs/code-examples/kms/index.html index 34a79a32f1e..db894f06470 100644 --- a/docs/docs/code-examples/kms/index.html +++ b/docs/docs/code-examples/kms/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/s3/index.html b/docs/docs/code-examples/s3/index.html index 132312bea1e..89e69791c27 100644 --- a/docs/docs/code-examples/s3/index.html +++ b/docs/docs/code-examples/s3/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/sns/index.html b/docs/docs/code-examples/sns/index.html index 37f8a8501da..3f3c7b62b7f 100644 --- a/docs/docs/code-examples/sns/index.html +++ b/docs/docs/code-examples/sns/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/sqs/index.html b/docs/docs/code-examples/sqs/index.html index 39f52c060c2..4f02367166a 100644 --- a/docs/docs/code-examples/sqs/index.html +++ b/docs/docs/code-examples/sqs/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/ssm/index.html b/docs/docs/code-examples/ssm/index.html index a01d2da6962..32b1a2c4b6d 100644 --- a/docs/docs/code-examples/ssm/index.html +++ b/docs/docs/code-examples/ssm/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/code-examples/sts/index.html b/docs/docs/code-examples/sts/index.html index 21eb387f9c7..5f9bf62ddf0 100644 --- a/docs/docs/code-examples/sts/index.html +++ b/docs/docs/code-examples/sts/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/configuring-sdk/custom-http/index.html b/docs/docs/configuring-sdk/custom-http/index.html index 3957b1e3b76..a63b3e321f4 100644 --- a/docs/docs/configuring-sdk/custom-http/index.html +++ b/docs/docs/configuring-sdk/custom-http/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/configuring-sdk/endpoints/index.html b/docs/docs/configuring-sdk/endpoints/index.html index ad0066844df..969ffb6d31e 100644 --- a/docs/docs/configuring-sdk/endpoints/index.html +++ b/docs/docs/configuring-sdk/endpoints/index.html @@ -25,11 +25,11 @@ - + - - + + @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • @@ -635,9 +644,13 @@

    With BaseEndpoint

    smithyendpoints.Endpoint, error, ) { if /* input params or caller context indicate we must route somewhere */ { - return smithyEndpoints.Endpoint{ - URI: url.Parse("https://custom.service.endpoint/"), + u, err := url.Parse("https://custom.service.endpoint/") + if err != nil { + return smithyendpoints.Endpoint{}, err } + return smithyendpoints.Endpoint{ + URI: *u, + }, nil } // delegate back to the default v2 resolver otherwise @@ -850,9 +863,13 @@

    Mutable endpoint

    smithyendpoints.Endpoint, error, ) { // This value will be used as-is when making the request. - return smithyEndpoints.Endpoint{ - URI: url.Parse("https://custom.endpoint.api/"), +
    u, err := url.Parse("https://custom.endpoint.api/") + if err != nil { + return smithyendpoints.Endpoint{}, err } + return smithyendpoints.Endpoint{ + URI: *u, + }, nil } client := svc.NewFromConfig(cfg, func (o *svc.Options) { @@ -862,7 +879,7 @@

    Mutable endpoint

    diff --git a/docs/docs/configuring-sdk/index.html b/docs/docs/configuring-sdk/index.html index 0c847814c54..a7ca627b9c1 100644 --- a/docs/docs/configuring-sdk/index.html +++ b/docs/docs/configuring-sdk/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • @@ -868,6 +877,14 @@

    Other Credentials Providers


    +
    +
    + Configuring Authentication +
    +

    Customizing service client authentication.

    +
    + +
    Configuring Client Endpoints diff --git a/docs/docs/configuring-sdk/index.xml b/docs/docs/configuring-sdk/index.xml index 1a523d7d2bd..a8f13801f68 100644 --- a/docs/docs/configuring-sdk/index.xml +++ b/docs/docs/configuring-sdk/index.xml @@ -14,6 +14,265 @@ + + Docs: Configuring Authentication + https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/auth/ + Fri, 01 Dec 2023 00:00:00 +0000 + + https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/auth/ + + + + <p>The AWS SDK for Go V2 provides the ability to configure the authentication +behavior service. In most cases, the default configuration will suffice, but +configuring custom authentication allows for additional behavior such as +working with pre-release service features.</p> +<h2 id="definitions">Definitions</h2> +<p>This section provides a high-level description of authentication components in +the AWS SDK for Go V2.</p> +<h3 id="authscheme"><code>AuthScheme</code></h3> +<p>An <a href="https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme">AuthScheme</a> is the +interface that defines the workflow through which the SDK retrieves a caller +identity and attaches it to an operation request.</p> +<p>An auth scheme uses the following components, described in detail further +below:</p> +<ul> +<li>A unique ID which identifies the scheme</li> +<li>An identity resolver, which returns a caller identity used in the signing +process (e.g. your AWS credentials)</li> +<li>A signer, which performs the actual injection of caller identity into the +operation&rsquo;s transport request (e.g. the <code>Authorization</code> HTTP header)</li> +</ul> +<p>Each service client options includes an <code>AuthSchemes</code> field, which by default +is populated with the list of auth schemes supported by that service.</p> +<h3 id="authschemeresolver"><code>AuthSchemeResolver</code></h3> +<p>Each service client options includes an <code>AuthSchemeResolver</code> field. This +interface, defined per-service, is the API called by the SDK to determine the +possible authentication options for each operation.</p> +<p><strong>IMPORTANT:</strong> The auth scheme resolver does NOT dictate what auth scheme is +used. It returns a list of schemes that <em>can</em> be used (&ldquo;options&rdquo;), the final +scheme is selected through a fixed algorithm described +<a href="#auth-scheme-resolution-workflow">here</a>.</p> +<h3 id="option"><code>Option</code></h3> +<p>Returned from a call to <code>ResolverAuthSchemes</code>, an <a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#Option">Option</a> represents a possible authentication option.</p> +<p>An option consists of three sets of information:</p> +<ul> +<li>An ID representing the possible scheme</li> +<li>An opaque set of properties to be provided to the scheme&rsquo;s identity resolver</li> +<li>An opaque set of properties to be provided to the scheme&rsquo;s signer</li> +</ul> +<h4 id="a-note-on-properties">a note on properties</h4> +<p>For 99% of use cases, callers need not be concerned with the opaque properties +for identity resolution and signing. The SDK will pull out the necessary +properties for each scheme and pass them to the strongly-typed interfaces +exposed in the SDK. For example, the default auth resolver for services encode +the SigV4 option to have signer properties for the signing name and region, the +values of which are passed to the client&rsquo;s configured +<a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#Signer">v4.HTTPSigner</a> implementation when SigV4 +is selected.</p> +<h3 id="identity"><code>Identity</code></h3> +<p>An <a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#Identity">Identity</a> is an abstract +representation of who the SDK caller is.</p> +<p>The most common type of identity used in the SDK is a set of <code>aws.Credentials</code>. +For most use cases, the caller need not concern themselves with <code>Identity</code> as +an abstraction and can work with the concrete types directly.</p> +<p><strong>Note:</strong> to preserve backwards compatibility and prevent API confusion, the +AWS SDK-specific identity type <code>aws.Credentials</code> does not directly satisfy the +<code>Identity</code> interface. This mapping is handled internally.</p> +<h3 id="identityresolver"><code>IdentityResolver</code></h3> +<p><a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#IdentityResolver">IdentityResolver</a> is the +interface through which an <code>Identity</code> is retrieved.</p> +<p>Concrete versions of <code>IdentityResolver</code> exist in the SDK in strongly-typed form +(e.g. <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#CredentialsProvider">aws.CredentialsProvider</a>), the +SDK handles this mapping internally.</p> +<p>A caller will only need to directly implement the <code>IdentityResolver</code> interface +when defining an external auth scheme.</p> +<h3 id="signer"><code>Signer</code></h3> +<p><a href="https://pkg.go.dev/github.com/aws/smithy-go/transport/http#Signer">Signer</a> is the interface +through which a request is supplemented with the retrieved caller <code>Identity</code>.</p> +<p>Concrete versions of <code>Signer</code> exist in the SDK in strongly-typed form +(e.g. <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#HTTPSigner">v4.HTTPSigner</a>), the SDK +handles this mapping internally.</p> +<p>A caller will only need to directly implement the <code>Signer</code> interface +when defining an external auth scheme.</p> +<h3 id="authresolverparameters"><code>AuthResolverParameters</code></h3> +<p>Each service takes a specific set of inputs which are passed to its resolution +function, defined in each service package as <code>AuthResolverParameters</code>.</p> +<p>The base resolver parameters are as follows:</p> +<table> +<thead> +<tr> +<th>name</th> +<th>type</th> +<th>description</th> +</tr> +</thead> +<tbody> +<tr> +<td><code>Operation</code></td> +<td><code>string</code></td> +<td>The name of the operation being invoked.</td> +</tr> +<tr> +<td><code>Region</code></td> +<td><code>string</code></td> +<td>The client&rsquo;s AWS region. Only present for services that use SigV4[A].</td> +</tr> +</tbody> +</table> +<p>If you are implementing your own resolver, you should never need to construct +your own instance of its parameters. The SDK will source these values +per-request and pass them to your implementation.</p> +<h2 id="auth-scheme-resolution-workflow">Auth scheme resolution workflow</h2> +<p>When you call an AWS service operation through the SDK, the following sequence +of actions occurs after the request has been serialized:</p> +<ol> +<li>The SDK calls the client&rsquo;s <code>AuthSchemeResolver.ResolveAuthSchemes()</code> API, +sourcing the input parameters as necessary, to obtain a list of possible +<a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#Option">Options</a> for the operation.</li> +<li>The SDK iterates over that list and selects the first scheme that satisfies +the following conditions. +<ul> +<li>A scheme with matching ID is present in the client&rsquo;s own <code>AuthSchemes</code> list</li> +<li>The scheme&rsquo;s identity resolver exists (is non-<code>nil</code>) on the client&rsquo;s Options +(checked via the scheme&rsquo;s <code>GetIdentityResolver</code> method, the mapping to the +concrete identity resolver types described above is handled internally) (1)</li> +</ul> +</li> +<li>Assuming a viable scheme was selected, the SDK invokes its +<code>GetIdentityResolver()</code> API to retrieve the caller&rsquo;s identity. For example, +the builtin SigV4 auth scheme will map to the client&rsquo;s <code>Credentials</code> provider +internally.</li> +<li>The SDK calls the identity resolver&rsquo;s <code>GetIdentity()</code> (e.g. +<code>aws.CredentialProvider.Retrieve()</code> for SigV4).</li> +<li>The SDK calls the endpoint resolver&rsquo;s <code>ResolveEndpoint()</code> to find the +endpoint for the request. The endpoint may include additional metadata that +influences the signing process (e.g. unique signing name for S3 Object Lambda).</li> +<li>The SDK calls the auth scheme&rsquo;s <code>Signer()</code> API to retrieve its signer, and +uses its <code>SignRequest()</code> API to sign the request with the +previously-retrieved caller identity.</li> +</ol> +<p>(1) If the SDK encounters the anonymous option (ID <code>smithy.api#noAuth</code>) in the +list, it is selected automatically, as there is no corresponding identity +resolver.</p> +<h2 id="natively-supported-authschemes">Natively-supported <code>AuthScheme</code>s</h2> +<p>The following auth schemes are natively supported by AWS SDK for Go V2.</p> +<table> +<thead> +<tr> +<th>Name</th> +<th>Scheme ID</th> +<th>Identity resolver</th> +<th>Signer</th> +<th>Notes</th> +</tr> +</thead> +<tbody> +<tr> +<td><a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html">SigV4</a></td> +<td><code>aws.auth#sigv4</code></td> +<td><a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Credentials">aws.CredentialsProvider</a></td> +<td><a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#Signer">v4.HTTPSigner</a></td> +<td>The current default for most AWS service operations.</td> +</tr> +<tr> +<td>SigV4A</td> +<td><code>aws.auth#sigv4a</code></td> +<td>aws.CredentialsProvider</td> +<td>n/a</td> +<td>SigV4A usage is limited at this time, the signer implementation is internal.</td> +</tr> +<tr> +<td>SigV4Express</td> +<td><code>com.amazonaws.s3#sigv4express</code></td> +<td><a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#ExpressCredentialsProvider">s3.ExpressCredentialsProvider</a></td> +<td>v4.HTTPSigner</td> +<td>Used for <a href="https://aws.amazon.com/s3/storage-classes/express-one-zone/">Express One Zone</a>.</td> +</tr> +<tr> +<td>HTTP Bearer</td> +<td><code>smithy.api#httpBearerAuth</code></td> +<td><a href="https://pkg.go.dev/github.com/aws/smithy-go/auth/bearer#TokenProvider">smithybearer.TokenProvider</a></td> +<td><a href="https://pkg.go.dev/github.com/aws/smithy-go/auth/bearer#Signer">smithybearer.Signer</a></td> +<td>Used by <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/codecatalyst">codecatalyst</a>.</td> +</tr> +<tr> +<td>Anonymous</td> +<td><code>smithy.api#noAuth</code></td> +<td>n/a</td> +<td>n/a</td> +<td>No authentication - no identity is required, and the request is not signed or authenticated.</td> +</tr> +</tbody> +</table> +<h3 id="identity-configuration">Identity configuration</h3> +<p>In AWS SDK for Go V2, the identity components of an auth scheme are +configured in SDK client <code>Options</code>. The SDK will automatically pick up and use +the values for these components for the scheme it selects when an operation is +called.</p> +<p><strong>Note:</strong> For backwards compatibility reasons, the SDK implicitly allows the +use of the anonymous auth scheme if no identity resolvers are configured. +This can be manually achieved by setting all identity resolvers on a client&rsquo;s +<code>Options</code> to <code>nil</code> (the sigv4 identity resolver can also be set to +<code>aws.AnonymousCredentials{}</code>).</p> +<h3 id="signer-configuration">Signer configuration</h3> +<p>In AWS SDK for Go V2, the signer components of an auth scheme are +configured in SDK client <code>Options</code>. The SDK will automatically pick up and use +the values for these components for the scheme it selects when an operation is +called. No additional configuration is necessary.</p> +<h4 id="custom-auth-scheme">Custom auth scheme</h4> +<p>In order to define a custom auth scheme and configure it for use, the caller +must do the following:</p> +<ol> +<li>Define an <a href="https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme">AuthScheme</a> +implementation</li> +<li>Register the scheme on the SDK client&rsquo;s <code>AuthSchemes</code> list</li> +<li>Instrument the SDK client&rsquo;s <code>AuthSchemeResolver</code> to return an auth <code>Option</code> +with the scheme&rsquo;s ID where applicable</li> +</ol> + + +<div class="pageinfo pageinfo-warning"> +<p>The following services have unique or customized authentication behavior. We +recommend you delegate to the default implementation and wrap accordingly if +you require custom authentication behavior therein:</p> +<table> +<thead> +<tr> +<th>Service</th> +<th>Notes</th> +</tr> +</thead> +<tbody> +<tr> +<td>S3</td> +<td>Conditional use of SigV4A and SigV4Express depending on operation input.</td> +</tr> +<tr> +<td>EventBridge</td> +<td>Conditional use of SigV4A depending on operation input.</td> +</tr> +<tr> +<td>Cognito</td> +<td>Certain operations are anonymous-only.</td> +</tr> +<tr> +<td>SSO</td> +<td>Certain operations are anonymous-only.</td> +</tr> +<tr> +<td>STS</td> +<td>Certain operations are anonymous-only.</td> +</tr> +</tbody> +</table> + +</div> + + + + + Docs: Configuring Client Endpoints https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/endpoints/ @@ -154,9 +413,13 @@ endpoint resolution using <code>EndpointResolverV2</code>.</p> </span></span><span style="display:flex;"><span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">error</span><span style="color:#000;font-weight:bold">,</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#8f5902;font-style:italic">/* input params or caller context indicate we must route somewhere */</span> <span style="color:#000;font-weight:bold">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyEndpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.service.endpoint/&#34;</span><span style="color:#000;font-weight:bold">),</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.service.endpoint/&#34;</span><span style="color:#000;font-weight:bold">)</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{},</span> <span style="color:#000">err</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> <span style="color:#204a87;font-weight:bold">nil</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// delegate back to the default v2 resolver otherwise @@ -369,9 +632,13 @@ resolver that returns a modifiable endpoint:</p> </span></span><span style="display:flex;"><span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">error</span><span style="color:#000;font-weight:bold">,</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// This value will be used as-is when making the request. -</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyEndpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.endpoint.api/&#34;</span><span style="color:#000;font-weight:bold">),</span> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.endpoint.api/&#34;</span><span style="color:#000;font-weight:bold">)</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{},</span> <span style="color:#000">err</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> <span style="color:#204a87;font-weight:bold">nil</span> </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#000">client</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">svc</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">NewFromConfig</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">cfg</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">o</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">svc</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Options</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> diff --git a/docs/docs/configuring-sdk/logging/index.html b/docs/docs/configuring-sdk/logging/index.html index 539ed23ca9e..417ed4c71c6 100644 --- a/docs/docs/configuring-sdk/logging/index.html +++ b/docs/docs/configuring-sdk/logging/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/configuring-sdk/retries-timeouts/index.html b/docs/docs/configuring-sdk/retries-timeouts/index.html index be3783c1e35..505e9a67683 100644 --- a/docs/docs/configuring-sdk/retries-timeouts/index.html +++ b/docs/docs/configuring-sdk/retries-timeouts/index.html @@ -108,7 +108,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -130,7 +130,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -148,7 +148,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/getting-started/index.html b/docs/docs/getting-started/index.html index 3ed4415d3db..77f0d685b8a 100644 --- a/docs/docs/getting-started/index.html +++ b/docs/docs/getting-started/index.html @@ -19,26 +19,26 @@ Getting Started with the AWS SDK for Go V2 | AWS SDK for Go V2 - - - + - - + - @@ -112,7 +112,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -134,7 +134,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -152,7 +152,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • @@ -499,7 +508,7 @@

    Getting Started with the AWS SDK for Go V2

    -

    The AWS SDK for Go requires Go 1.15 or later. You can view your current version of Go by running the following command.

    +

    The AWS SDK for Go requires Go 1.19 or later. You can view your current version of Go by running the following command:

    go version
     

    For information about installing or upgrading your version of Go, see https://golang.org/doc/install.

    Get an Amazon Account

    @@ -611,7 +620,7 @@

    Invoke an Operation

    - Last modified August 4, 2021: Typo in getting-started.md (#1365) (95b48d1440) + Last modified December 19, 2023: true up migration guide: iface, endpoints, auth, request customization, s3crypto (#2431) (33023c3b7f)
    diff --git a/docs/docs/handling-errors/index.html b/docs/docs/handling-errors/index.html index 91664a5bbb4..ca17f29f16c 100644 --- a/docs/docs/handling-errors/index.html +++ b/docs/docs/handling-errors/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/index.html b/docs/docs/index.html index a0af4809fb6..9505f899191 100644 --- a/docs/docs/index.html +++ b/docs/docs/index.html @@ -20,10 +20,8 @@ Developer Guide | AWS SDK for Go V2 - + @@ -103,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -125,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -143,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • @@ -479,14 +486,7 @@

    Developer Guide

    - - -
    -

    On October 31, 2023, the AWS SDK for Go (v1 and v2) will start following the Go release policy cadence. See the blog post for more information.

    - -
    - -

    Welcome to the AWS SDK for Go. The AWS SDK for Go V2 provides APIs and utilities that developers can use to build Go +

    Welcome to the AWS SDK for Go. The AWS SDK for Go V2 provides APIs and utilities that developers can use to build Go applications that use AWS services, such as Amazon Elastic Compute Cloud (Amazon EC2) and Amazon Simple Storage Service (Amazon S3).

    The SDK removes the complexity of coding directly against a web service interface. It hides a lot of the lower-level @@ -571,6 +571,14 @@

    +
    +
    + Frequently Asked Questions +
    +

    Answers to some commonly-asked questions about the AWS SDK for Go V2

    +
    + +
    Unit Testing with the AWS SDK for Go V2 @@ -608,7 +616,7 @@
    diff --git a/docs/docs/index.xml b/docs/docs/index.xml index 1e02fc8051d..e015c8a87aa 100644 --- a/docs/docs/index.xml +++ b/docs/docs/index.xml @@ -15,6 +15,245 @@ + + Docs: Timing SDK operations + https://aws.github.io/aws-sdk-go-v2/docs/faq/timing-operations/ + Mon, 01 Jan 0001 00:00:00 +0000 + + https://aws.github.io/aws-sdk-go-v2/docs/faq/timing-operations/ + + + + <p>When debugging timeout / latency issues in the SDK, it is critical to identify +the components of the operation lifecycle which are taking more time to execute +than expected. As a starting point, you will generally need to inspect the +timing breakdown between the overall operation call and the HTTP call itself.</p> +<p>The following sample program implements a basic instrumentation probe in terms +of <code>smithy-go</code> middleware for SQS clients and demonstrates how it is used. The +probe emits the following information for each operation call:</p> +<ul> +<li>AWS request ID</li> +<li>service ID</li> +<li>operation name</li> +<li>operation invocation time</li> +<li>http call time</li> +</ul> +<p>Each emitted message is prefixed with a unique (to a single operation) +&ldquo;invocation ID&rdquo; which is set at the beginning of the handler stack.</p> +<p>The entry point for instrumentation is exposed as <code>WithOperationTiming</code>, which +is parameterized to accept a message handling function which will receive +instrumentation &ldquo;events&rdquo; as formatted strings. <code>PrintfMSGHandler</code> is provided +as a convenience which will simply dump messages to stdout.</p> +<p>The service used here is interchangeable - ALL service client options accept +<code>APIOptions</code> and an <code>HTTPClient</code> as configuration. For example, +<code>WithOperationTiming</code> could instead be declared as:</p> +<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">WithOperationTiming</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">msgHandler</span> <span style="color:#204a87;font-weight:bold">func</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">string</span><span style="color:#000;font-weight:bold">))</span> <span style="color:#204a87;font-weight:bold">func</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">s3</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Options</span><span style="color:#000;font-weight:bold">)</span> +</span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000">WithOperationTiming</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">msgHandler</span> <span style="color:#204a87;font-weight:bold">func</span><span style="color:#000;font-weight:bold">(</span><span style="color:#204a87;font-weight:bold">string</span><span style="color:#000;font-weight:bold">))</span> <span style="color:#204a87;font-weight:bold">func</span><span style="color:#000;font-weight:bold">(</span><span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">dynamodb</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Options</span><span style="color:#000;font-weight:bold">)</span> +</span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic">// etc. +</span></span></span></code></pre></div><p>If you change it, be sure to change the signature of the function it returns as +well.</p> +<pre tabindex="0"><code>import ( + &#34;context&#34; + &#34;fmt&#34; + &#34;log&#34; + &#34;net/http&#34; + &#34;sync&#34; + &#34;time&#34; + + awsmiddleware &#34;github.com/aws/aws-sdk-go-v2/aws/middleware&#34; + awshttp &#34;github.com/aws/aws-sdk-go-v2/aws/transport/http&#34; + &#34;github.com/aws/aws-sdk-go-v2/config&#34; + &#34;github.com/aws/aws-sdk-go-v2/service/sqs&#34; + &#34;github.com/aws/smithy-go/middleware&#34; + smithyrand &#34;github.com/aws/smithy-go/rand&#34; +) + +// WithOperationTiming instruments an SQS client to dump timing information for +// the following spans: +// - overall operation time +// - HTTPClient call time +// +// This instrumentation will also emit the request ID, service name, and +// operation name for each invocation. +// +// Accepts a message &#34;handler&#34; which is invoked with formatted messages to be +// handled externally, you can use the declared PrintfMSGHandler to simply dump +// these values to stdout. +func WithOperationTiming(msgHandler func(string)) func(*sqs.Options) { + return func(o *sqs.Options) { + o.APIOptions = append(o.APIOptions, addTimingMiddlewares(msgHandler)) + o.HTTPClient = &amp;timedHTTPClient{ + client: awshttp.NewBuildableClient(), + msgHandler: msgHandler, + } + } +} + +// PrintfMSGHandler writes messages to stdout. +func PrintfMSGHandler(msg string) { + fmt.Printf(&#34;%s\n&#34;, msg) +} + +type invokeIDKey struct{} + +func setInvokeID(ctx context.Context, id string) context.Context { + return middleware.WithStackValue(ctx, invokeIDKey{}, id) +} + +func getInvokeID(ctx context.Context) string { + id, _ := middleware.GetStackValue(ctx, invokeIDKey{}).(string) + return id +} + +func timeSpan(ctx context.Context, name string, consumer func(string)) func() { + start := time.Now() + return func() { + elapsed := time.Now().Sub(start) + consumer(fmt.Sprintf(&#34;[%s] %s: %s&#34;, getInvokeID(ctx), name, elapsed)) + } +} + +type timedHTTPClient struct { + client *awshttp.BuildableClient + msgHandler func(string) +} + +func (c *timedHTTPClient) Do(r *http.Request) (*http.Response, error) { + defer timeSpan(r.Context(), &#34;http&#34;, c.msgHandler)() + + resp, err := c.client.Do(r) + if err != nil { + return nil, fmt.Errorf(&#34;inner client do: %v&#34;, err) + } + + return resp, nil +} + +type addInvokeIDMiddleware struct { + msgHandler func(string) +} + +func (*addInvokeIDMiddleware) ID() string { return &#34;addInvokeID&#34; } + +func (*addInvokeIDMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, md middleware.Metadata, err error, +) { + id, err := smithyrand.NewUUID(smithyrand.Reader).GetUUID() + if err != nil { + return out, md, fmt.Errorf(&#34;new uuid: %v&#34;, err) + } + + return next.HandleInitialize(setInvokeID(ctx, id), in) +} + +type timeOperationMiddleware struct { + msgHandler func(string) +} + +func (*timeOperationMiddleware) ID() string { return &#34;timeOperation&#34; } + +func (m *timeOperationMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + middleware.InitializeOutput, middleware.Metadata, error, +) { + defer timeSpan(ctx, &#34;operation&#34;, m.msgHandler)() + return next.HandleInitialize(ctx, in) +} + +type emitMetadataMiddleware struct { + msgHandler func(string) +} + +func (*emitMetadataMiddleware) ID() string { return &#34;emitMetadata&#34; } + +func (m *emitMetadataMiddleware) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + middleware.InitializeOutput, middleware.Metadata, error, +) { + out, md, err := next.HandleInitialize(ctx, in) + + invokeID := getInvokeID(ctx) + requestID, _ := awsmiddleware.GetRequestIDMetadata(md) + service := awsmiddleware.GetServiceID(ctx) + operation := awsmiddleware.GetOperationName(ctx) + m.msgHandler(fmt.Sprintf(`[%s] requestID = &#34;%s&#34;`, invokeID, requestID)) + m.msgHandler(fmt.Sprintf(`[%s] service = &#34;%s&#34;`, invokeID, service)) + m.msgHandler(fmt.Sprintf(`[%s] operation = &#34;%s&#34;`, invokeID, operation)) + + return out, md, err +} + +func addTimingMiddlewares(mh func(string)) func(*middleware.Stack) error { + return func(s *middleware.Stack) error { + if err := s.Initialize.Add(&amp;timeOperationMiddleware{msgHandler: mh}, middleware.Before); err != nil { + return fmt.Errorf(&#34;add time operation middleware: %v&#34;, err) + } + if err := s.Initialize.Add(&amp;addInvokeIDMiddleware{msgHandler: mh}, middleware.Before); err != nil { + return fmt.Errorf(&#34;add invoke id middleware: %v&#34;, err) + } + if err := s.Initialize.Insert(&amp;emitMetadataMiddleware{msgHandler: mh}, &#34;RegisterServiceMetadata&#34;, middleware.After); err != nil { + return fmt.Errorf(&#34;add emit metadata middleware: %v&#34;, err) + } + return nil + } +} + +func main() { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + log.Fatal(fmt.Errorf(&#34;load default config: %v&#34;, err)) + } + + svc := sqs.NewFromConfig(cfg, WithOperationTiming(PrintfMSGHandler)) + + var wg sync.WaitGroup + + for i := 0; i &lt; 6; i++ { + wg.Add(1) + go func() { + defer wg.Done() + + _, err = svc.ListQueues(context.Background(), nil) + if err != nil { + fmt.Println(fmt.Errorf(&#34;list queues: %v&#34;, err)) + } + }() + } + wg.Wait() +} +</code></pre><p>A sample output of this program:</p> +<pre tabindex="0"><code>[e9a801bb-c51d-45c8-8e9f-a202e263fde8] http: 192.24067ms +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] requestID = &#34;dbee3082-96a3-5b23-adca-6d005696fa94&#34; +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] service = &#34;SQS&#34; +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] operation = &#34;ListQueues&#34; +[e9a801bb-c51d-45c8-8e9f-a202e263fde8] operation: 193.098393ms +[0740f0e0-953e-4328-94fc-830a5052e763] http: 195.185732ms +[0740f0e0-953e-4328-94fc-830a5052e763] requestID = &#34;48b301fa-fc9f-5f1f-9007-5c783caa9322&#34; +[0740f0e0-953e-4328-94fc-830a5052e763] service = &#34;SQS&#34; +[0740f0e0-953e-4328-94fc-830a5052e763] operation = &#34;ListQueues&#34; +[0740f0e0-953e-4328-94fc-830a5052e763] operation: 195.725491ms +[c0589832-f351-4cc7-84f1-c656eb79dbd7] http: 200.52383ms +[444030d0-6743-4de5-bd91-bc40b2b94c55] http: 200.525919ms +[c0589832-f351-4cc7-84f1-c656eb79dbd7] requestID = &#34;4a73cc82-b47b-56e1-b327-9100744e1b1f&#34; +[c0589832-f351-4cc7-84f1-c656eb79dbd7] service = &#34;SQS&#34; +[c0589832-f351-4cc7-84f1-c656eb79dbd7] operation = &#34;ListQueues&#34; +[c0589832-f351-4cc7-84f1-c656eb79dbd7] operation: 201.214365ms +[444030d0-6743-4de5-bd91-bc40b2b94c55] requestID = &#34;ca1523ed-1879-5610-bf5d-7e6fd84cabee&#34; +[444030d0-6743-4de5-bd91-bc40b2b94c55] service = &#34;SQS&#34; +[444030d0-6743-4de5-bd91-bc40b2b94c55] operation = &#34;ListQueues&#34; +[444030d0-6743-4de5-bd91-bc40b2b94c55] operation: 201.197071ms +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] http: 206.449568ms +[12b2b39d-df86-4648-a436-ff0482d13340] http: 206.526603ms +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] requestID = &#34;64229710-b552-56ed-8f96-ca927567ec7b&#34; +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] service = &#34;SQS&#34; +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] operation = &#34;ListQueues&#34; +[079e8dbd-bb93-43ab-89e5-a7bb392b86a5] operation: 207.252357ms +[12b2b39d-df86-4648-a436-ff0482d13340] requestID = &#34;76d9cbc0-07aa-58aa-98b7-9642c79f9851&#34; +[12b2b39d-df86-4648-a436-ff0482d13340] service = &#34;SQS&#34; +[12b2b39d-df86-4648-a436-ff0482d13340] operation = &#34;ListQueues&#34; +[12b2b39d-df86-4648-a436-ff0482d13340] operation: 207.360621ms +</code></pre> + + + Docs: Getting Started with the AWS SDK for Go V2 https://aws.github.io/aws-sdk-go-v2/docs/getting-started/ @@ -24,7 +263,7 @@ - <p>The AWS SDK for Go requires Go 1.15 or later. You can view your current version of Go by running the following command.</p> + <p>The AWS SDK for Go requires Go 1.19 or later. You can view your current version of Go by running the following command:</p> <pre tabindex="0"><code>go version </code></pre><p>For information about installing or upgrading your version of Go, see <a href="https://golang.org/doc/install">https://golang.org/doc/install</a>.</p> <h2 id="get-an-amazon-account">Get an Amazon Account</h2> @@ -323,12 +562,22 @@ struct should not be accessed in the event that a non-nil error is returned by t </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> </span></span></code></pre></div><p>For more information on error handling, including how to inspect for specific error types, see the <a href="https://aws.github.io/aws-sdk-go-v2/docs/handling-errors/">Handling Errors</a> documentation.</p> -<h4 id="responses-with-ioreadcloser">Responses with io.ReadCloser</h4> -<p>Some API operations return a response struct that contain an output member that is an <code>io.ReadCloser</code>. If you&rsquo;re making -requests with these operations, always be sure to call <code>io.ReadCloser</code> member&rsquo;s <code>Close</code> method after you&rsquo;ve completed -reading the content.</p> -<p>For example Amazon S3 <code>GetObject</code> operation returns a response -whose <code>Body</code> member is an <code>io.ReadCloser</code>:</p> +<h4 id="responses-with-ioreadcloser">Responses with <code>io.ReadCloser</code></h4> +<p>Some API operations return a response struct that contain an output member that +is an <code>io.ReadCloser</code>. This will be the case for API operations that expose +some element of their output in the body of the HTTP response itself.</p> +<p>For example, Amazon S3 <code>GetObject</code> operation returns a response +whose <code>Body</code> member is an <code>io.ReadCloser</code> for accessing the object payload.</p> + + +<div class="pageinfo pageinfo-warning"> +<p><strong>You MUST ALWAYS <code>Close()</code> any <code>io.ReadCloser</code> output members, regardless of +whether you&rsquo;ve consumed its content. Failure to do so can leak resources and +potentially create issues with reading response bodies for operations called in +the future.</strong></p> + +</div> + <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#000">resp</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">s3svc</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">GetObject</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">context</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">TODO</span><span style="color:#000;font-weight:bold">(),</span> <span style="color:#ce5c00;font-weight:bold">&amp;</span><span style="color:#000">s3</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">GetObjectInput</span><span style="color:#000;font-weight:bold">{</span><span style="color:#ce5c00;font-weight:bold">...</span><span style="color:#000;font-weight:bold">})</span> </span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// handle error @@ -346,7 +595,7 @@ whose <code>Body</code> member is an <code>io.ReadCloser</c <p>All service operation output structs include a <code>ResultMetadata</code> member of type <a href="https://pkg.go.dev/github.com/aws/smithy-go/middleware#Metadata">middleware.Metadata</a>. <code>middleware.Metadata</code> is used by the SDK middleware to provide additional information from a service response that is not modeled by the service. This includes metadata -like the <code>RequestID</code>. For example to retrieve the <code>RequestID</code> associated with a service response to assit AWS Support in +like the <code>RequestID</code>. For example to retrieve the <code>RequestID</code> associated with a service response to assist AWS Support in troubleshooting a request:</p> <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span> <span style="color:#4e9a06">&#34;fmt&#34;</span> </span></span><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span> <span style="color:#4e9a06">&#34;log&#34;</span> @@ -1378,6 +1627,265 @@ for environment (EC2)</strong>, earlier in this topic.)</p> + + Docs: Configuring Authentication + https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/auth/ + Fri, 01 Dec 2023 00:00:00 +0000 + + https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/auth/ + + + + <p>The AWS SDK for Go V2 provides the ability to configure the authentication +behavior service. In most cases, the default configuration will suffice, but +configuring custom authentication allows for additional behavior such as +working with pre-release service features.</p> +<h2 id="definitions">Definitions</h2> +<p>This section provides a high-level description of authentication components in +the AWS SDK for Go V2.</p> +<h3 id="authscheme"><code>AuthScheme</code></h3> +<p>An <a href="https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme">AuthScheme</a> is the +interface that defines the workflow through which the SDK retrieves a caller +identity and attaches it to an operation request.</p> +<p>An auth scheme uses the following components, described in detail further +below:</p> +<ul> +<li>A unique ID which identifies the scheme</li> +<li>An identity resolver, which returns a caller identity used in the signing +process (e.g. your AWS credentials)</li> +<li>A signer, which performs the actual injection of caller identity into the +operation&rsquo;s transport request (e.g. the <code>Authorization</code> HTTP header)</li> +</ul> +<p>Each service client options includes an <code>AuthSchemes</code> field, which by default +is populated with the list of auth schemes supported by that service.</p> +<h3 id="authschemeresolver"><code>AuthSchemeResolver</code></h3> +<p>Each service client options includes an <code>AuthSchemeResolver</code> field. This +interface, defined per-service, is the API called by the SDK to determine the +possible authentication options for each operation.</p> +<p><strong>IMPORTANT:</strong> The auth scheme resolver does NOT dictate what auth scheme is +used. It returns a list of schemes that <em>can</em> be used (&ldquo;options&rdquo;), the final +scheme is selected through a fixed algorithm described +<a href="#auth-scheme-resolution-workflow">here</a>.</p> +<h3 id="option"><code>Option</code></h3> +<p>Returned from a call to <code>ResolverAuthSchemes</code>, an <a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#Option">Option</a> represents a possible authentication option.</p> +<p>An option consists of three sets of information:</p> +<ul> +<li>An ID representing the possible scheme</li> +<li>An opaque set of properties to be provided to the scheme&rsquo;s identity resolver</li> +<li>An opaque set of properties to be provided to the scheme&rsquo;s signer</li> +</ul> +<h4 id="a-note-on-properties">a note on properties</h4> +<p>For 99% of use cases, callers need not be concerned with the opaque properties +for identity resolution and signing. The SDK will pull out the necessary +properties for each scheme and pass them to the strongly-typed interfaces +exposed in the SDK. For example, the default auth resolver for services encode +the SigV4 option to have signer properties for the signing name and region, the +values of which are passed to the client&rsquo;s configured +<a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#Signer">v4.HTTPSigner</a> implementation when SigV4 +is selected.</p> +<h3 id="identity"><code>Identity</code></h3> +<p>An <a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#Identity">Identity</a> is an abstract +representation of who the SDK caller is.</p> +<p>The most common type of identity used in the SDK is a set of <code>aws.Credentials</code>. +For most use cases, the caller need not concern themselves with <code>Identity</code> as +an abstraction and can work with the concrete types directly.</p> +<p><strong>Note:</strong> to preserve backwards compatibility and prevent API confusion, the +AWS SDK-specific identity type <code>aws.Credentials</code> does not directly satisfy the +<code>Identity</code> interface. This mapping is handled internally.</p> +<h3 id="identityresolver"><code>IdentityResolver</code></h3> +<p><a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#IdentityResolver">IdentityResolver</a> is the +interface through which an <code>Identity</code> is retrieved.</p> +<p>Concrete versions of <code>IdentityResolver</code> exist in the SDK in strongly-typed form +(e.g. <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#CredentialsProvider">aws.CredentialsProvider</a>), the +SDK handles this mapping internally.</p> +<p>A caller will only need to directly implement the <code>IdentityResolver</code> interface +when defining an external auth scheme.</p> +<h3 id="signer"><code>Signer</code></h3> +<p><a href="https://pkg.go.dev/github.com/aws/smithy-go/transport/http#Signer">Signer</a> is the interface +through which a request is supplemented with the retrieved caller <code>Identity</code>.</p> +<p>Concrete versions of <code>Signer</code> exist in the SDK in strongly-typed form +(e.g. <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#HTTPSigner">v4.HTTPSigner</a>), the SDK +handles this mapping internally.</p> +<p>A caller will only need to directly implement the <code>Signer</code> interface +when defining an external auth scheme.</p> +<h3 id="authresolverparameters"><code>AuthResolverParameters</code></h3> +<p>Each service takes a specific set of inputs which are passed to its resolution +function, defined in each service package as <code>AuthResolverParameters</code>.</p> +<p>The base resolver parameters are as follows:</p> +<table> +<thead> +<tr> +<th>name</th> +<th>type</th> +<th>description</th> +</tr> +</thead> +<tbody> +<tr> +<td><code>Operation</code></td> +<td><code>string</code></td> +<td>The name of the operation being invoked.</td> +</tr> +<tr> +<td><code>Region</code></td> +<td><code>string</code></td> +<td>The client&rsquo;s AWS region. Only present for services that use SigV4[A].</td> +</tr> +</tbody> +</table> +<p>If you are implementing your own resolver, you should never need to construct +your own instance of its parameters. The SDK will source these values +per-request and pass them to your implementation.</p> +<h2 id="auth-scheme-resolution-workflow">Auth scheme resolution workflow</h2> +<p>When you call an AWS service operation through the SDK, the following sequence +of actions occurs after the request has been serialized:</p> +<ol> +<li>The SDK calls the client&rsquo;s <code>AuthSchemeResolver.ResolveAuthSchemes()</code> API, +sourcing the input parameters as necessary, to obtain a list of possible +<a href="https://pkg.go.dev/github.com/aws/smithy-go/auth#Option">Options</a> for the operation.</li> +<li>The SDK iterates over that list and selects the first scheme that satisfies +the following conditions. +<ul> +<li>A scheme with matching ID is present in the client&rsquo;s own <code>AuthSchemes</code> list</li> +<li>The scheme&rsquo;s identity resolver exists (is non-<code>nil</code>) on the client&rsquo;s Options +(checked via the scheme&rsquo;s <code>GetIdentityResolver</code> method, the mapping to the +concrete identity resolver types described above is handled internally) (1)</li> +</ul> +</li> +<li>Assuming a viable scheme was selected, the SDK invokes its +<code>GetIdentityResolver()</code> API to retrieve the caller&rsquo;s identity. For example, +the builtin SigV4 auth scheme will map to the client&rsquo;s <code>Credentials</code> provider +internally.</li> +<li>The SDK calls the identity resolver&rsquo;s <code>GetIdentity()</code> (e.g. +<code>aws.CredentialProvider.Retrieve()</code> for SigV4).</li> +<li>The SDK calls the endpoint resolver&rsquo;s <code>ResolveEndpoint()</code> to find the +endpoint for the request. The endpoint may include additional metadata that +influences the signing process (e.g. unique signing name for S3 Object Lambda).</li> +<li>The SDK calls the auth scheme&rsquo;s <code>Signer()</code> API to retrieve its signer, and +uses its <code>SignRequest()</code> API to sign the request with the +previously-retrieved caller identity.</li> +</ol> +<p>(1) If the SDK encounters the anonymous option (ID <code>smithy.api#noAuth</code>) in the +list, it is selected automatically, as there is no corresponding identity +resolver.</p> +<h2 id="natively-supported-authschemes">Natively-supported <code>AuthScheme</code>s</h2> +<p>The following auth schemes are natively supported by AWS SDK for Go V2.</p> +<table> +<thead> +<tr> +<th>Name</th> +<th>Scheme ID</th> +<th>Identity resolver</th> +<th>Signer</th> +<th>Notes</th> +</tr> +</thead> +<tbody> +<tr> +<td><a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html">SigV4</a></td> +<td><code>aws.auth#sigv4</code></td> +<td><a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Credentials">aws.CredentialsProvider</a></td> +<td><a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/signer/v4#Signer">v4.HTTPSigner</a></td> +<td>The current default for most AWS service operations.</td> +</tr> +<tr> +<td>SigV4A</td> +<td><code>aws.auth#sigv4a</code></td> +<td>aws.CredentialsProvider</td> +<td>n/a</td> +<td>SigV4A usage is limited at this time, the signer implementation is internal.</td> +</tr> +<tr> +<td>SigV4Express</td> +<td><code>com.amazonaws.s3#sigv4express</code></td> +<td><a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#ExpressCredentialsProvider">s3.ExpressCredentialsProvider</a></td> +<td>v4.HTTPSigner</td> +<td>Used for <a href="https://aws.amazon.com/s3/storage-classes/express-one-zone/">Express One Zone</a>.</td> +</tr> +<tr> +<td>HTTP Bearer</td> +<td><code>smithy.api#httpBearerAuth</code></td> +<td><a href="https://pkg.go.dev/github.com/aws/smithy-go/auth/bearer#TokenProvider">smithybearer.TokenProvider</a></td> +<td><a href="https://pkg.go.dev/github.com/aws/smithy-go/auth/bearer#Signer">smithybearer.Signer</a></td> +<td>Used by <a href="https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/codecatalyst">codecatalyst</a>.</td> +</tr> +<tr> +<td>Anonymous</td> +<td><code>smithy.api#noAuth</code></td> +<td>n/a</td> +<td>n/a</td> +<td>No authentication - no identity is required, and the request is not signed or authenticated.</td> +</tr> +</tbody> +</table> +<h3 id="identity-configuration">Identity configuration</h3> +<p>In AWS SDK for Go V2, the identity components of an auth scheme are +configured in SDK client <code>Options</code>. The SDK will automatically pick up and use +the values for these components for the scheme it selects when an operation is +called.</p> +<p><strong>Note:</strong> For backwards compatibility reasons, the SDK implicitly allows the +use of the anonymous auth scheme if no identity resolvers are configured. +This can be manually achieved by setting all identity resolvers on a client&rsquo;s +<code>Options</code> to <code>nil</code> (the sigv4 identity resolver can also be set to +<code>aws.AnonymousCredentials{}</code>).</p> +<h3 id="signer-configuration">Signer configuration</h3> +<p>In AWS SDK for Go V2, the signer components of an auth scheme are +configured in SDK client <code>Options</code>. The SDK will automatically pick up and use +the values for these components for the scheme it selects when an operation is +called. No additional configuration is necessary.</p> +<h4 id="custom-auth-scheme">Custom auth scheme</h4> +<p>In order to define a custom auth scheme and configure it for use, the caller +must do the following:</p> +<ol> +<li>Define an <a href="https://pkg.go.dev/github.com/aws/smithy-go/transport/http#AuthScheme">AuthScheme</a> +implementation</li> +<li>Register the scheme on the SDK client&rsquo;s <code>AuthSchemes</code> list</li> +<li>Instrument the SDK client&rsquo;s <code>AuthSchemeResolver</code> to return an auth <code>Option</code> +with the scheme&rsquo;s ID where applicable</li> +</ol> + + +<div class="pageinfo pageinfo-warning"> +<p>The following services have unique or customized authentication behavior. We +recommend you delegate to the default implementation and wrap accordingly if +you require custom authentication behavior therein:</p> +<table> +<thead> +<tr> +<th>Service</th> +<th>Notes</th> +</tr> +</thead> +<tbody> +<tr> +<td>S3</td> +<td>Conditional use of SigV4A and SigV4Express depending on operation input.</td> +</tr> +<tr> +<td>EventBridge</td> +<td>Conditional use of SigV4A depending on operation input.</td> +</tr> +<tr> +<td>Cognito</td> +<td>Certain operations are anonymous-only.</td> +</tr> +<tr> +<td>SSO</td> +<td>Certain operations are anonymous-only.</td> +</tr> +<tr> +<td>STS</td> +<td>Certain operations are anonymous-only.</td> +</tr> +</tbody> +</table> + +</div> + + + + + Docs: Amazon RDS Utilities https://aws.github.io/aws-sdk-go-v2/docs/sdk-utilities/rds/ @@ -1650,9 +2158,13 @@ endpoint resolution using <code>EndpointResolverV2</code>.</p> </span></span><span style="display:flex;"><span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">error</span><span style="color:#000;font-weight:bold">,</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#8f5902;font-style:italic">/* input params or caller context indicate we must route somewhere */</span> <span style="color:#000;font-weight:bold">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyEndpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.service.endpoint/&#34;</span><span style="color:#000;font-weight:bold">),</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.service.endpoint/&#34;</span><span style="color:#000;font-weight:bold">)</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{},</span> <span style="color:#000">err</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> <span style="color:#204a87;font-weight:bold">nil</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// delegate back to the default v2 resolver otherwise @@ -1865,9 +2377,13 @@ resolver that returns a modifiable endpoint:</p> </span></span><span style="display:flex;"><span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">error</span><span style="color:#000;font-weight:bold">,</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> </span></span><span style="display:flex;"><span> <span style="color:#8f5902;font-style:italic">// This value will be used as-is when making the request. -</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyEndpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> -</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.endpoint.api/&#34;</span><span style="color:#000;font-weight:bold">),</span> +</span></span></span><span style="display:flex;"><span><span style="color:#8f5902;font-style:italic"></span> <span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">url</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Parse</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://custom.endpoint.api/&#34;</span><span style="color:#000;font-weight:bold">)</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">if</span> <span style="color:#000">err</span> <span style="color:#ce5c00;font-weight:bold">!=</span> <span style="color:#204a87;font-weight:bold">nil</span> <span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{},</span> <span style="color:#000">err</span> </span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">}</span> +</span></span><span style="display:flex;"><span> <span style="color:#204a87;font-weight:bold">return</span> <span style="color:#000">smithyendpoints</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Endpoint</span><span style="color:#000;font-weight:bold">{</span> +</span></span><span style="display:flex;"><span> <span style="color:#000">URI</span><span style="color:#000;font-weight:bold">:</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">u</span><span style="color:#000;font-weight:bold">,</span> +</span></span><span style="display:flex;"><span> <span style="color:#000;font-weight:bold">},</span> <span style="color:#204a87;font-weight:bold">nil</span> </span></span><span style="display:flex;"><span><span style="color:#000;font-weight:bold">}</span> </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="color:#000">client</span> <span style="color:#ce5c00;font-weight:bold">:=</span> <span style="color:#000">svc</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">NewFromConfig</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">cfg</span><span style="color:#000;font-weight:bold">,</span> <span style="color:#204a87;font-weight:bold">func</span> <span style="color:#000;font-weight:bold">(</span><span style="color:#000">o</span> <span style="color:#ce5c00;font-weight:bold">*</span><span style="color:#000">svc</span><span style="color:#000;font-weight:bold">.</span><span style="color:#000">Options</span><span style="color:#000;font-weight:bold">)</span> <span style="color:#000;font-weight:bold">{</span> diff --git a/docs/docs/making-requests/index.html b/docs/docs/making-requests/index.html index 807483e4508..01a448eb57c 100644 --- a/docs/docs/making-requests/index.html +++ b/docs/docs/making-requests/index.html @@ -25,11 +25,11 @@ - + - - + + @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • @@ -680,12 +689,22 @@

    Passing Parameters to a Servi }

    For more information on error handling, including how to inspect for specific error types, see the Handling Errors documentation.

    -

    Responses with io.ReadCloser

    -

    Some API operations return a response struct that contain an output member that is an io.ReadCloser. If you’re making -requests with these operations, always be sure to call io.ReadCloser member’s Close method after you’ve completed -reading the content.

    -

    For example Amazon S3 GetObject operation returns a response -whose Body member is an io.ReadCloser:

    +

    Responses with io.ReadCloser

    +

    Some API operations return a response struct that contain an output member that +is an io.ReadCloser. This will be the case for API operations that expose +some element of their output in the body of the HTTP response itself.

    +

    For example, Amazon S3 GetObject operation returns a response +whose Body member is an io.ReadCloser for accessing the object payload.

    + + +
    +

    You MUST ALWAYS Close() any io.ReadCloser output members, regardless of +whether you’ve consumed its content. Failure to do so can leak resources and +potentially create issues with reading response bodies for operations called in +the future.

    + +
    +
    resp, err := s3svc.GetObject(context.TODO(), &s3.GetObjectInput{...})
     if err != nil {
         // handle error
    @@ -703,7 +722,7 @@ 

    Responses with io.ReadCloser

    All service operation output structs include a ResultMetadata member of type middleware.Metadata. middleware.Metadata is used by the SDK middleware to provide additional information from a service response that is not modeled by the service. This includes metadata -like the RequestID. For example to retrieve the RequestID associated with a service response to assit AWS Support in +like the RequestID. For example to retrieve the RequestID associated with a service response to assist AWS Support in troubleshooting a request:

    import "fmt"
     import "log"
    @@ -1004,7 +1023,7 @@ 

    Using Waiters

    diff --git a/docs/docs/middleware/index.html b/docs/docs/middleware/index.html index 74c9d2f0850..275a5b2e813 100644 --- a/docs/docs/middleware/index.html +++ b/docs/docs/middleware/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/migrating/index.html b/docs/docs/migrating/index.html index e684f009de5..f102be89260 100644 --- a/docs/docs/migrating/index.html +++ b/docs/docs/migrating/index.html @@ -100,7 +100,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -122,7 +122,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -140,7 +140,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • @@ -424,6 +433,7 @@
  • +
  • Mocking and *iface
  • Credentials & Credential Providers
  • @@ -514,8 +534,7 @@

    Migrating to the AWS SDK for Go V2

    Minimum Go Version

    -

    The AWS SDK for Go V2 requires a minimum version of Go 1.15. Migration from AWS SDK for Go to AWS SDK for Go V2 -might require you to upgrade your application by one or more Go versions. The latest version of Go can be downloaded on +

    The AWS SDK for Go V2 requires a minimum Go version of 1.19. Migration from v1 to v2 The latest version of Go can be downloaded on the Downloads page. See the Release History for more information about each Go version release, and relevant information required for upgrading.

    Modularization

    @@ -670,7 +689,58 @@
    Migrating from NewSessio if err != nil { // handle error } -

    Credentials & Credential Providers

    +

    Mocking and *iface

    +

    The *iface packages and interfaces therein (e.g. s3iface.S3API) +have been removed. These interface definitions are not stable since they are +broken every time a service adds a new operation.

    +

    Usage of *iface should be replaced by scoped caller-defined interfaces for +the service operations being used:

    +
    // V1
    +
    +import "io"
    +
    +import "github.com/aws/aws-sdk-go/service/s3"
    +import "github.com/aws/aws-sdk-go/service/s3/s3iface"
    +
    +func GetObjectBytes(client s3iface.S3API, bucket, key string) ([]byte, error) {
    +    object, err := client.GetObject(&s3.GetObjectInput{
    +        Bucket: &bucket,
    +        Key:    &key,
    +    })
    +    if err != nil {
    +        return nil, err
    +    }
    +    defer object.Body.Close()
    +
    +    return io.ReadAll(object.Body)
    +}
    +
    // V2
    +
    +import "context"
    +import "io"
    +
    +import "github.com/aws/aws-sdk-go-v2/service/s3"
    +
    +
    +type GetObjectAPIClient interface {
    +    GetObject(context.Context, *s3.GetObjectInput, ...func(*s3.Options)) (*s3.GetObjectOutput, error)
    +}
    +
    +func GetObjectBytes(ctx context.Context, client GetObjectAPIClient, bucket, key string) ([]byte, error) {
    +    object, err := api.GetObject(ctx, &s3.GetObjectInput{
    +        Bucket: &bucket,
    +        Key:    &key,
    +    })
    +    if err != nil {
    +        return nil, err
    +    }
    +    defer object.Body.Close()
    +
    +    return io.ReadAll(object.Body)
    +}
    +

    See the testing guide for more +information.

    +

    Credentials & Credential Providers

    The aws/credentials package and associated credential providers have been relocated to the credentials package location. The credentials package is a Go module that you retrieve by using go get.

    @@ -1019,15 +1089,22 @@
    Example 1

    The endpoints package no longer exists in the AWS SDK for Go V2. Each service client now embeds its required AWS endpoint metadata within the client package. This reduces the overall binary size of compiled applications by no longer including endpoint metadata for services not used by your application.

    +

    Additionally, each service now exposes its own interface for endpoint +resolution in EndpointResolverV2. Each API takes a unique set of parameters +for a service EndpointParameters, the values of which are sourced by the SDK +from various locations when an operation is invoked.

    By default, service clients use their configured AWS Region to resolve the service endpoint for the target Region. If -your application requires a custom endpoint to be specified for a particular service and region, you can specify -a custom aws.EndpointResolver using the EndpointResolver field on the +your application requires a custom endpoint, you can specify custom behavior on EndpointResolverV2 field on the aws.Config structure. If your application implements a custom -endpoints.Resolver you must migrate it to conform to the -aws.EndpointResolver interface. aws.EndpointResolverFunc is provided as -a convenient way to wrap a resolver function to satisfy the aws.EndpointResolver interface.

    +endpoints.Resolver you must +migrate it to conform to this new per-service interface.

    For more information on endpoints and implementing a custom resolver, see Configuring Client Endpoints.

    +

    Authentication

    +

    The AWS SDK for Go V2 supports more advanced authentication behavior, which +enables the use of newer AWS service features such as codecatalyst and S3 +Express One Zone. Additionally, this behavior can be customized on a per-client +basis.

    Invoking API Operations

    The number of service client operation methods have been reduced significantly. The <OperationName>Request, <OperationName>WithContext, and <OperationName> methods have all been consolidated into single operation method, <OperationName>.

    @@ -1235,7 +1312,445 @@

    Example

    s3.NewBucketExistsWaiter constructor to create a s3.BucketExistsWaiter. The s3.BucketExistsWaiter provides a Wait method which can be used to wait for a bucket to become available.

    -

    Features

    +

    Presigned Requests

    +

    The V1 SDK technically supported presigning any AWS SDK operation, however, +this does not accurately represent what is actually supported at the service +level (and in reality most AWS service operations do not support presigning).

    +

    AWS SDK for Go V2 resolves this by exposing specific PresignClient +implementations in service packages with specific APIs for supported +presignable operations.

    +

    Note: If a service is missing presigning support for an operation that you +were successfully using in SDK v1, please let us know by +filing an issue on GitHub.

    +

    Uses of Presign and +PresignRequest must +be converted to use service-specific presigning clients.

    +

    The following example shows how to migrate presigning of an S3 GetObject +request:

    +
    // V1
    +
    +import (
    +	"fmt"
    +	"time"
    +
    +	"github.com/aws/aws-sdk-go/aws"
    +	"github.com/aws/aws-sdk-go/aws/session"
    +	"github.com/aws/aws-sdk-go/service/s3"
    +)
    +
    +func main() {
    +	sess := session.Must(session.NewSessionWithOptions(session.Options{
    +		SharedConfigState: session.SharedConfigEnable,
    +	}))
    +
    +	svc := s3.New(sess)
    +	req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
    +		Bucket: aws.String("bucket"),
    +		Key:    aws.String("key"),
    +	})
    +
    +	// pattern 1
    +	url1, err := req.Presign(20 * time.Minute)
    +	if err != nil {
    +		panic(err)
    +	}
    +	fmt.Println(url1)
    +
    +	// pattern 2
    +	url2, header, err := req.PresignRequest(20 * time.Minute)
    +	if err != nil {
    +		panic(err)
    +	}
    +	fmt.Println(url2, header)
    +}
    +
    // V2
    +
    +import (
    +	"context"
    +	"fmt"
    +	"time"
    +
    +	"github.com/aws/aws-sdk-go-v2/aws"
    +	"github.com/aws/aws-sdk-go-v2/config"
    +	"github.com/aws/aws-sdk-go-v2/service/s3"
    +)
    +
    +func main() {
    +	cfg, err := config.LoadDefaultConfig(context.Background())
    +	if err != nil {
    +		panic(err)
    +	}
    +
    +	svc := s3.NewPresignClient(s3.NewFromConfig(cfg))
    +	req, err := svc.PresignGetObject(context.Background(), &s3.GetObjectInput{
    +		Bucket: aws.String("bucket"),
    +		Key:    aws.String("key"),
    +	}, func(o *s3.PresignOptions) {
    +		o.Expires = 20 * time.Minute
    +	})
    +	if err != nil {
    +		panic(err)
    +	}
    +
    +	fmt.Println(req.Method, req.URL, req.SignedHeader)
    +}
    +

    Request customization

    +

    The monolithic request.Request API +has been re-compartmentalized.

    +

    Operation input/output

    +

    The opaque Request fields Params and Data, which hold the operation input +and output structures respectively, are now accessible within specific +middleware phases as input/output:

    +

    Request handlers which reference Request.Params and Request.Data must be migrated to middleware.

    +

    migrating Params

    +
    // V1
    +
    +import (
    +    "github.com/aws/aws-sdk-go/aws"
    +    "github.com/aws/aws-sdk-go/aws/request"
    +    "github.com/aws/aws-sdk-go/aws/session"
    +    "github.com/aws/aws-sdk-go/service/s3"
    +)
    +
    +func withPutObjectDefaultACL(acl string) request.Option {
    +    return func(r *request.Request) {
    +        in, ok := r.Params.(*s3.PutObjectInput)
    +        if !ok {
    +            return
    +        }
    +
    +        if in.ACL == nil {
    +            in.ACL = aws.String(acl)
    +        }
    +        r.Params = in
    +    }
    +}
    +
    +func main() {
    +    sess := session.Must(session.NewSession())
    +    sess.Handlers.Validate.PushBack(withPutObjectDefaultACL(s3.ObjectCannedACLBucketOwnerFullControl))
    +
    +    // ...
    +}
    +
    // V2
    +
    +import (
    +    "context"
    +
    +    "github.com/aws/aws-sdk-go-v2/service/s3"
    +    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    +    "github.com/aws/smithy-go/middleware"
    +    smithyhttp "github.com/aws/smithy-go/transport/http"
    +)
    +
    +type withPutObjectDefaultACL struct {
    +    acl types.ObjectCannedACL
    +}
    +
    +// implements middleware.InitializeMiddleware, which runs BEFORE a request has
    +// been serialized and can act on the operation input
    +var _ middleware.InitializeMiddleware = (*withPutObjectDefaultACL)(nil)
    +
    +func (*withPutObjectDefaultACL) ID() string {
    +    return "withPutObjectDefaultACL"
    +}
    +
    +func (m *withPutObjectDefaultACL) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
    +    out middleware.InitializeOutput, metadata middleware.Metadata, err error,
    +) {
    +    input, ok := in.Parameters.(*s3.PutObjectInput)
    +    if !ok {
    +        return next.HandleInitialize(ctx, in)
    +    }
    +
    +    if len(input.ACL) == 0 {
    +        input.ACL = m.acl
    +    }
    +    in.Parameters = input
    +    return next.HandleInitialize(ctx, in)
    +}
    +
    +// create a helper function to simplify instrumentation of our middleware
    +func WithPutObjectDefaultACL(acl types.ObjectCannedACL) func (*s3.Options) {
    +    return func(o *s3.Options) {
    +        o.APIOptions = append(o.APIOptions, func (s *middleware.Stack) error {
    +            return s.Initialize.Add(&withPutObjectDefaultACL{acl: acl}, middleware.After)
    +        })
    +    }
    +}
    +
    +func main() {
    +    cfg, err := config.LoadDefaultConfig(context.Background())
    +    if err != nil {
    +        // ...
    +    }
    +
    +    svc := s3.NewFromConfig(cfg, WithPutObjectDefaultACL(types.ObjectCannedACLBucketOwnerFullControl))
    +    // ...
    +}
    +

    migrating Data

    +
    // V1
    +
    +import (
    +    "github.com/aws/aws-sdk-go/aws"
    +    "github.com/aws/aws-sdk-go/aws/request"
    +    "github.com/aws/aws-sdk-go/aws/session"
    +    "github.com/aws/aws-sdk-go/service/s3"
    +)
    +
    +func readPutObjectOutput(r *request.Request) {
    +        output, ok := r.Data.(*s3.PutObjectOutput)
    +        if !ok {
    +            return
    +        }
    +
    +        // ...
    +    }
    +}
    +
    +func main() {
    +    sess := session.Must(session.NewSession())
    +    sess.Handlers.Unmarshal.PushBack(readPutObjectOutput)
    +
    +    svc := s3.New(sess)
    +    // ...
    +}
    +
    // V2
    +
    +import (
    +    "context"
    +
    +    "github.com/aws/aws-sdk-go-v2/config"
    +    "github.com/aws/aws-sdk-go-v2/service/s3"
    +    "github.com/aws/smithy-go/middleware"
    +    smithyhttp "github.com/aws/smithy-go/transport/http"
    +)
    +
    +type readPutObjectOutput struct{}
    +
    +var _ middleware.DeserializeMiddleware = (*readPutObjectOutput)(nil)
    +
    +func (*readPutObjectOutput) ID() string {
    +    return "readPutObjectOutput"
    +}
    +
    +func (*readPutObjectOutput) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) (
    +    out middleware.DeserializeOutput, metadata middleware.Metadata, err error,
    +) {
    +    out, metadata, err = next.HandleDeserialize(ctx, in)
    +    if err != nil {
    +        // ...
    +    }
    +
    +    output, ok := in.Parameters.(*s3.PutObjectOutput)
    +    if !ok {
    +        return out, metadata, err
    +    }
    +
    +    // inspect output...
    +
    +    return out, metadata, err
    +}
    +
    +func WithReadPutObjectOutput(o *s3.Options) {
    +    o.APIOptions = append(o.APIOptions, func (s *middleware.Stack) error {
    +        return s.Initialize.Add(&withReadPutObjectOutput{}, middleware.Before)
    +    })
    +}
    +
    +func main() {
    +    cfg, err := config.LoadDefaultConfig(context.Background())
    +    if err != nil {
    +        // ...
    +    }
    +
    +    svc := s3.NewFromConfig(cfg, WithReadPutObjectOutput)
    +    // ...
    +}
    +

    HTTP request/response

    +

    The HTTPRequest and HTTPResponse fields from Request are now exposed in +specific middleware phases. Since middleware is transport-agnostic, you must +perform a type assertion on the middleware input or output to reveal the +underlying HTTP request or response.

    +

    Request handlers which reference Request.HTTPRequest and +Request.HTTPResponse must be migrated to middleware.

    +

    migrating HTTPRequest

    +
    // V1
    +
    +import (
    +    "github.com/aws/aws-sdk-go/aws/request"
    +    "github.com/aws/aws-sdk-go/aws/session"
    +)
    +
    +func withHeader(header, val string) request.Option {
    +    return func(r *request.Request) {
    +        request.HTTPRequest.Header.Set(header, val)
    +    }
    +}
    +
    +func main() {
    +    sess := session.Must(session.NewSession())
    +    sess.Handlers.Build.PushBack(withHeader("x-user-header", "..."))
    +
    +    svc := s3.New(sess)
    +    // ...
    +}
    +
    // V2
    +
    +import (
    +    "context"
    +    "fmt"
    +
    +    "github.com/aws/aws-sdk-go-v2/config"
    +    "github.com/aws/aws-sdk-go-v2/service/s3"
    +    "github.com/aws/smithy-go/middleware"
    +    smithyhttp "github.com/aws/smithy-go/transport/http"
    +)
    +
    +type withHeader struct {
    +    header, val string
    +}
    +
    +// implements middleware.BuildMiddleware, which runs AFTER a request has been
    +// serialized and can operate on the transport request
    +var _ middleware.BuildMiddleware = (*withHeader)(nil)
    +
    +func (*withHeader) ID() string {
    +    return "withHeader"
    +}
    +
    +func (m *withHeader) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (
    +    out middleware.BuildOutput, metadata middleware.Metadata, err error,
    +) {
    +    req, ok := in.Request.(*smithyhttp.Request)
    +    if !ok {
    +        return out, metadata, fmt.Errorf("unrecognized transport type %T", in.Request)
    +    }
    +
    +    req.Header.Set(m.header, m.val)
    +    return next.HandleBuild(ctx, in)
    +}
    +
    +func WithHeader(header, val string) func (*s3.Options) {
    +    return func(o *s3.Options) {
    +        o.APIOptions = append(o.APIOptions, func (s *middleware.Stack) error {
    +            return s.Build.Add(&withHeader{
    +                header: header,
    +                val: val,
    +            }, middleware.After)
    +        })
    +    }
    +}
    +
    +func main() {
    +    cfg, err := config.LoadDefaultConfig(context.Background())
    +    if err != nil {
    +        // ...
    +    }
    +
    +    svc := s3.NewFromConfig(cfg, WithHeader("x-user-header", "..."))
    +    // ...
    +}
    +

    Handler phases

    +

    SDK v2 middleware phases are the successor to v1 handler phases.

    +

    The following table provides a rough mapping of v1 handler phases to their +equivalent location within the V2 middleware stack:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    v1 handler namev2 middleware phase
    ValidateInitialize
    BuildSerialize
    SignFinalize
    Sendn/a (1)
    ValidateResponseDeserialize
    UnmarshalDeserialize
    UnmarshalMetadataDeserialize
    UnmarshalErrorDeserialize
    RetryFinalize, after "Retry" middleware (2)
    AfterRetryFinalize, before "Retry" middleware, post-next.HandleFinalize() (2,3)
    CompleteAttemptFinalize, end of step
    CompleteInitialize, start of step, post-next.HandleInitialize() (3)
    +

    (1) The Send phase in v1 is effectively the wrapped HTTP client round-trip in +v2. This behavior is controlled by the HTTPClient field on client options.

    +

    (2) Any middleware after the "Retry" middleware in the Finalize step will be +part of the retry loop.

    +

    (3) The middleware “stack” at operation time is built into a +repeatedly-decorated handler function. Each handler is responsible for calling +the next one in the chain. This implicitly means that a middleware step can +also take action AFTER its next step has been called.

    +

    For example, for the Initialize step, which is at the top of the stack, this +means Initialize middlewares that take action after calling the next handler +effectively operate at the end of the request:

    +
    // V2
    +
    +import (
    +    "context"
    +
    +    "github.com/aws/smithy-go/middleware"
    +)
    +
    +type onComplete struct{}
    +
    +var _ middleware.InitializeMiddleware = (*onComplete)(nil)
    +
    +func (*onComplete) ID() string {
    +    return "onComplete"
    +}
    +
    +func (*onComplete) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) (
    +    out middleware.InitializeOutput, metadata middleware.Metadata, err error,
    +) {
    +    out, metadata, err = next.HandleInitialize(ctx, in)
    +
    +    // the entire operation was invoked above - the deserialized response is
    +    // available opaquely in out.Result, run post-op actions here...
    +
    +    return out, metadata, err
    +}
    +

    Features

    Amazon EC2 Instance Metadata Service

    The AWS SDK for Go V2 provides an Amazon EC2 Instance Metadata Service (IMDS) client that you can use to query the local IMDS when executing your application on an Amazon EC2 instance. The IMDS client is @@ -1283,7 +1798,32 @@

    Amazon CloudFront Signing Utilities

    The AWS SDK for Go V2 provides Amazon CloudFront signing utilities in a Go module outside the service client import path. This module can be retrieved by using go get.

    go get github.com/aws/aws-sdk-go-v2/feature/cloudfront/sign
    -
    +

    Amazon S3 Encryption Client

    +

    Starting in AWS SDK for Go V2, the Amazon S3 encryption client is a separate +module under AWS Crypto Tools. The latest version of the S3 encryption client +for Go, 3.x, is now available at https://github.com/aws/amazon-s3-encryption-client-go. +This module can be retrieved by using go get:

    +
    go get github.com/aws/amazon-s3-encryption-client-go/v3
    +

    The separate EncryptionClient +(v1, v2) +and DecryptionClient +(v1, v2) +APIs have been replaced with a single client, +S3EncryptionClientV3, +that exposes both encrypt and decrypt functionality.

    +

    Like other service clients in AWS SDK for Go V2, the operation APIs have +been condensed:

    + +

    To learn how to migrate to the 3.x major version of the encryption client, see +this guide.

    +
    @@ -1299,7 +1839,7 @@

    Amazon CloudFront Signing Utilities

    diff --git a/docs/docs/sdk-utilities/cloudfront/index.html b/docs/docs/sdk-utilities/cloudfront/index.html index 2318ba31bca..bae6e2a0728 100644 --- a/docs/docs/sdk-utilities/cloudfront/index.html +++ b/docs/docs/sdk-utilities/cloudfront/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/sdk-utilities/ec2-imds/index.html b/docs/docs/sdk-utilities/ec2-imds/index.html index 770025b1cfe..58191f41f75 100644 --- a/docs/docs/sdk-utilities/ec2-imds/index.html +++ b/docs/docs/sdk-utilities/ec2-imds/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/sdk-utilities/index.html b/docs/docs/sdk-utilities/index.html index abcf74f10fb..03a7bd1f919 100644 --- a/docs/docs/sdk-utilities/index.html +++ b/docs/docs/sdk-utilities/index.html @@ -100,7 +100,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -122,7 +122,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -140,7 +140,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/sdk-utilities/rds/index.html b/docs/docs/sdk-utilities/rds/index.html index 55fc9bb30c1..bcc53917cb5 100644 --- a/docs/docs/sdk-utilities/rds/index.html +++ b/docs/docs/sdk-utilities/rds/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/sdk-utilities/s3/index.html b/docs/docs/sdk-utilities/s3/index.html index 917cd552749..649069748c4 100644 --- a/docs/docs/sdk-utilities/s3/index.html +++ b/docs/docs/sdk-utilities/s3/index.html @@ -109,7 +109,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -131,7 +131,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -149,7 +149,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/compliance-validation/index.html b/docs/docs/security/compliance-validation/index.html index fd0de572116..c7db2c532e7 100644 --- a/docs/docs/security/compliance-validation/index.html +++ b/docs/docs/security/compliance-validation/index.html @@ -111,7 +111,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -133,7 +133,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -151,7 +151,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/data-protection/index.html b/docs/docs/security/data-protection/index.html index 1877fc9c244..1abc60e7255 100644 --- a/docs/docs/security/data-protection/index.html +++ b/docs/docs/security/data-protection/index.html @@ -105,7 +105,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -127,7 +127,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -145,7 +145,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/disaster-recovery-resiliency/index.html b/docs/docs/security/disaster-recovery-resiliency/index.html index a2e6214760b..90f540b9385 100644 --- a/docs/docs/security/disaster-recovery-resiliency/index.html +++ b/docs/docs/security/disaster-recovery-resiliency/index.html @@ -111,7 +111,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -133,7 +133,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -151,7 +151,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/iam/index.html b/docs/docs/security/iam/index.html index 014bfda3bdf..a78762465bf 100644 --- a/docs/docs/security/iam/index.html +++ b/docs/docs/security/iam/index.html @@ -108,7 +108,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -130,7 +130,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -148,7 +148,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/index.html b/docs/docs/security/index.html index a2acd4105db..e26e1f9f0db 100644 --- a/docs/docs/security/index.html +++ b/docs/docs/security/index.html @@ -101,7 +101,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -123,7 +123,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -141,7 +141,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/infrastructure-security/index.html b/docs/docs/security/infrastructure-security/index.html index e643b0f902f..5784c79e40e 100644 --- a/docs/docs/security/infrastructure-security/index.html +++ b/docs/docs/security/infrastructure-security/index.html @@ -110,7 +110,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -132,7 +132,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -150,7 +150,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/security/tls/index.html b/docs/docs/security/tls/index.html index 2827a7502d5..cfaf24819e6 100644 --- a/docs/docs/security/tls/index.html +++ b/docs/docs/security/tls/index.html @@ -108,7 +108,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -130,7 +130,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -148,7 +148,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/docs/unit-testing/index.html b/docs/docs/unit-testing/index.html index 1d9468a56a6..20fcac6ab8d 100644 --- a/docs/docs/unit-testing/index.html +++ b/docs/docs/unit-testing/index.html @@ -104,7 +104,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -126,7 +126,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > @@ -144,7 +144,9 @@
  • Configuring the SDK
  • Middleware +
  • + FAQ / Troubleshooting +
  • Testing
  • diff --git a/docs/index.html b/docs/index.html index 5c5582c2de9..5816c5879cf 100644 --- a/docs/index.html +++ b/docs/index.html @@ -124,7 +124,7 @@ aria-label="Search this site…" autocomplete="off" - data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.810a5299d837b395cdd69648bfec2e99.json" + data-offline-search-index-json-src="/aws-sdk-go-v2/offline-search-index.ba2b7a89f1555398e1c5839c9aee3bc1.json" data-offline-search-base-href="/" data-offline-search-max-results="10" > diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 14977d4e8e0..ecf4777649c 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -3,10 +3,13 @@ xmlns:xhtml="http://www.w3.org/1999/xhtml"> https://aws.github.io/aws-sdk-go-v2/docs/ - 2023-06-29T10:16:09-04:00 + 2023-12-19T13:14:51-05:00 + + https://aws.github.io/aws-sdk-go-v2/docs/faq/timing-operations/ + 2023-12-21T11:24:35-05:00 https://aws.github.io/aws-sdk-go-v2/docs/getting-started/ - 2021-08-04T10:26:41-07:00 + 2023-12-19T13:14:51-05:00 https://aws.github.io/aws-sdk-go-v2/docs/code-examples/cloudwatch/ 2021-01-14T12:54:53-08:00 @@ -42,10 +45,10 @@ 2021-01-14T12:54:53-08:00 https://aws.github.io/aws-sdk-go-v2/docs/migrating/ - 2022-05-16T15:58:05-04:00 + 2023-12-19T17:39:08-05:00 https://aws.github.io/aws-sdk-go-v2/docs/making-requests/ - 2022-10-06T12:21:54-07:00 + 2023-12-21T11:24:35-05:00 https://aws.github.io/aws-sdk-go-v2/docs/handling-errors/ 2021-06-23T15:45:17-07:00 @@ -55,6 +58,9 @@ https://aws.github.io/aws-sdk-go-v2/docs/middleware/ 2021-01-15T13:01:18-08:00 + + https://aws.github.io/aws-sdk-go-v2/docs/faq/ + 2023-12-21T11:24:35-05:00 https://aws.github.io/aws-sdk-go-v2/docs/unit-testing/ 2022-01-05T13:43:00-08:00 @@ -67,6 +73,9 @@ https://aws.github.io/aws-sdk-go-v2/docs/code-examples/ 2022-08-10T20:22:46+00:00 + + https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/auth/ + 2023-12-19T10:46:55-05:00 https://aws.github.io/aws-sdk-go-v2/docs/sdk-utilities/rds/ 2023-02-14T12:11:29-05:00 @@ -78,7 +87,7 @@ 2020-11-17T11:36:43-08:00 https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/endpoints/ - 2023-07-31T13:48:53-04:00 + 2023-10-06T22:55:58+03:00 https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/custom-http/ 2020-12-23T13:28:16-08:00