

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Configurar endpoints de cliente
<a name="configure-endpoints"></a>

**Atenção**  
 A resolução de endpoints é um tópico avançado do SDK. Ao alterar essas configurações, você corre o risco de quebrar seu código. As configurações padrão devem ser aplicáveis à maioria dos usuários em ambientes de produção. 

 AWS SDK para Go Ele fornece a capacidade de configurar um endpoint personalizado para ser usado em um serviço. Na maioria dos casos, a configuração padrão é suficiente. A configuração de endpoints personalizados permite um comportamento adicional, como trabalhar com versões de pré-lançamento de um serviço. 

## Personalização
<a name="customization"></a>

 Há duas “versões” da configuração de resolução de endpoints no SDK. 
+  v2, lançada no terceiro trimestre de 2023, configurada por meio de: 
  +  `EndpointResolverV2` 
  +  `BaseEndpoint` 
+  v1, lançada junto com o SDK, configurada por meio de: 
  +  `EndpointResolver` 

 Recomendamos que os usuários da resolução de endpoint v1 migrem para a v2 para ter acesso aos novos recursos de serviço relacionados ao endpoint. 

## V2: `EndpointResolverV2` \+ `BaseEndpoint`
<a name="v2-endpointresolverv2--baseendpoint"></a>

 Na resolução v2, `EndpointResolverV2` é o mecanismo definitivo pelo qual ocorre a resolução do endpoint. O método `ResolveEndpoint` do resolvedor é invocado como parte do fluxo de trabalho para cada solicitação que você faz no SDK. O nome do host do `Endpoint` retornado pelo resolvedor é usado **como está** ao fazer a solicitação (no entanto, os serializadores de operação ainda podem ser anexados ao caminho HTTP). 

 A resolução v2 inclui uma configuração adicional no nível do cliente, `BaseEndpoint`, que é usada para especificar um nome de host “base” para a instância do serviço. O valor definido aqui não é definitivo. Em última análise, ele é passado como um parâmetro para o `EndpointResolverV2` do cliente quando a resolução final ocorre (continue lendo para obter mais informações sobre os parâmetros `EndpointResolverV2`). A implementação do resolvedor então tem a oportunidade de inspecionar e possivelmente modificar esse valor para determinar o endpoint final. 

 Por exemplo, se você realizar uma solicitação `GetObject` do S3 em determinado bucket com um cliente em que você especificou um `BaseEndpoint`, o resolvedor padrão injetará o bucket no nome do host se ele for compatível com o host virtual (supondo que você não tenha desativado a hospedagem virtual na configuração do cliente). 

 Na prática, provavelmente `BaseEndpoint` será usado para direcionar o cliente a uma instância de desenvolvimento ou prévia de um serviço. 

### Parâmetros do `EndpointResolverV2`
<a name="endpointresolverv2-parameters"></a>

 Cada serviço usa um conjunto específico de entradas que são passadas para sua função de resolução, definida em cada pacote de serviços como `EndpointParameters`. 

 Cada serviço inclui os seguintes parâmetros básicos, que são usados para facilitar a resolução geral de endpoints na AWS: 


|  name  |  type  |  descrição  | 
| --- | --- | --- | 
|  Region  |  string  |  A AWS região do cliente  | 
|  Endpoint  |  string  |  O valor definido de BaseEndpoint na configuração do cliente  | 
|  UseFips  |  bool  |  Se os endpoints FIPS estão habilitados na configuração do cliente  | 
|  UseDualStack  |  bool  |  Se os endpoints de pilha dupla estão habilitados na configuração do cliente  | 

 Os serviços podem especificar parâmetros adicionais necessários para a resolução. Por exemplo, `EndpointParameters` do S3 incluem o nome do bucket, bem como várias configurações de recursos específicos do S3, como se o endereçamento de host virtual está habilitado. 

 Se você estiver implementando seu próprio `EndpointResolverV2`, nunca será necessário construir sua própria instância de `EndpointParameters`. O SDK fornece os valores por solicitação e os transmite para sua implementação. 

### Uma observação sobre o Amazon S3
<a name="a-note-about-amazon-s3"></a>

 O Amazon S3 é um serviço complexo com muitos de seus recursos modelados por meio de personalizações complexas de endpoints, como hospedagem virtual de bucket, S3 MRAP e muito mais. 

 Por isso, recomendamos não substituir a implementação `EndpointResolverV2` no cliente do S3. Se você precisar estender seu comportamento de resolução, talvez enviando solicitações a uma pilha de desenvolvimento local com considerações adicionais de endpoint, recomendamos encapsular a implementação padrão de forma que ela retorne ao padrão como alternativa (conforme mostrado nos exemplos abaixo). 

### Exemplos
<a name="examples"></a>

#### Com `BaseEndpoint`
<a name="with-baseendpoint"></a>

 O trecho de código a seguir mostra como direcionar o cliente do S3 para uma instância local de um serviço, que neste exemplo está hospedada no dispositivo de loopback na porta 8080. 

```
client := s3.NewFromConfig(cfg, func (o *svc.Options) {
    o.BaseEndpoint = aws.String("https://localhost:8080/")
})
```

#### Com `EndpointResolverV2`
<a name="with-endpointresolverv2"></a>

 O trecho de código a seguir mostra como injetar um comportamento personalizado na resolução do endpoint do S3 usando `EndpointResolverV2`. 

```
import (
    "context"
    "net/url"

    "github.com/aws/aws-sdk-go-v2/service/s3"
    smithyendpoints "github.com/aws/smithy-go/endpoints"
)

type resolverV2 struct {
    // you could inject additional application context here as well
}

func (*resolverV2) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (
        smithyendpoints.Endpoint, error,
    ) {
    if /* input params or caller context indicate we must route somewhere */ {
        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
    return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
}

func main() {
    // load config...

    client := s3.NewFromConfig(cfg, func (o *s3.Options) {
        o.EndpointResolverV2 = &resolverV2{
            // ...
        }
    })
}
```

#### Com ambos
<a name="with-both"></a>

 O exemplo de programa a seguir demonstra a interação entre `BaseEndpoint` e `EndpointResolverV2`. **Este é um caso de uso avançado:** 

```
import (
    "context"
    "fmt"
    "log"
    "net/url"

    "github.com/aws/aws-sdk-go-v2"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    smithyendpoints "github.com/aws/smithy-go/endpoints"
)

type resolverV2 struct {}

func (*resolverV2) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (
        smithyendpoints.Endpoint, error,
    ) {
    // s3.Options.BaseEndpoint is accessible here:
    fmt.Printf("The endpoint provided in config is %s\n", *params.Endpoint)

    // fallback to default
    return s3.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
}

func main() {
    cfg, err := config.LoadDefaultConfig(context.Background())
    if (err != nil) {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg, func (o *s3.Options) {
        o.BaseEndpoint = aws.String("https://endpoint.dev/")
        o.EndpointResolverV2 = &resolverV2{}
    })

    // ignore the output, this is just for demonstration
    client.ListBuckets(context.Background(), nil)
}
```

 Quando executado, o programa acima gera o seguinte: 

```
The endpoint provided in config is https://endpoint.dev/
```

## V1: `EndpointResolver`
<a name="v1-endpointresolver"></a>

**Atenção**  
 A resolução de endpoint da v1 é mantida para fins de compatibilidade com versões anteriores e é isolada do comportamento moderno na resolução de endpoint da v2. Ela só será usada se o campo `EndpointResolver` for definido pelo chamador.   
 O uso da v1 provavelmente impedirá que você acesse os recursos de serviço relacionados ao endpoint introduzidos com ou após o lançamento da resolução v2. Consulte instruções sobre como fazer upgrade em “Migração”. 

 A [EndpointResolver](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointResolver)pode ser configurado para fornecer uma lógica de resolução de endpoint personalizada para clientes de serviço. Você pode usar um resolvedor de endpoint personalizado a fim de substituir a lógica de resolução de endpoint de um serviço para todos os endpoints ou apenas para um endpoint regional específico. O resolvedor de endpoint personalizado pode acionar a lógica de resolução de endpoint do serviço para recuar se um resolvedor personalizado não quiser resolver um endpoint solicitado. [EndpointResolverWithOptionsFunc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointResolverWithOptionsFunc)pode ser usado para agrupar facilmente funções para satisfazer a `EndpointResolverWithOptions` interface. 

 A `EndpointResolver` pode ser facilmente configurado passando o resolvedor empacotado com [WithEndpointResolverWithOptions](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#WithEndpointResolverWithOptions)to [LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig), permitindo a capacidade de substituir os endpoints ao carregar as credenciais, bem como configurar o resultado `aws.Config` com seu resolvedor de endpoint personalizado. 

 O resolvedor de endpoint recebe o serviço e a região como uma string, permitindo que o resolvedor conduza dinamicamente seu comportamento. Cada pacote de cliente de serviço tem uma constante `ServiceID` exportada que pode ser usada para determinar qual cliente de serviço está invocando o resolvedor de endpoint. 

 Um resolvedor de endpoint pode usar o valor do erro [EndpointNotFoundError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointNotFoundError)sentinela para acionar a resolução alternativa para a lógica de resolução padrão do cliente do serviço. Isso permite substituir seletivamente um ou mais endpoints sem precisar lidar com a lógica de fallback. 

 Se a implementação do resolvedor de endpoint retornar um erro diferente de `EndpointNotFoundError`, a resolução do endpoint será interrompida e a operação de serviço retornará um erro para a aplicação. 

### Exemplos
<a name="examples-1"></a>

#### Com fallback
<a name="with-fallback"></a>

 O trecho de código a seguir mostra como um único endpoint de serviço pode ser substituído para o DynamoDB pelo comportamento com fallback para outros endpoints: 

```
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    if service == dynamodb.ServiceID && region == "us-west-2" {
        return aws.Endpoint{
            PartitionID:   "aws",
            URL:           "https://test.us-west-2.amazonaws.com",
            SigningRegion: "us-west-2",
        }, nil
    }
    // returning EndpointNotFoundError will allow the service to fallback to it's default resolution
    return aws.Endpoint{}, &aws.EndpointNotFoundError{}
})

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
```

#### Sem fallback
<a name="without-fallback"></a>

 O trecho de código a seguir mostra como um único endpoint de serviço pode ser substituído para o DynamoDB pelo comportamento sem fallback para outros endpoints: 

```
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    if service == dynamodb.ServiceID && region == "us-west-2" {
        return aws.Endpoint{
            PartitionID:   "aws",
            URL:           "https://test.us-west-2.amazonaws.com",
            SigningRegion: "us-west-2",
        }, nil
    }
    return aws.Endpoint{}, fmt.Errorf("unknown endpoint requested")
})

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
```

### Endpoints imutáveis
<a name="immutable-endpoints"></a>

**Atenção**  
 Definir um endpoint como imutável pode impedir que alguns recursos do cliente de serviço funcionem corretamente e pode resultar em um comportamento indefinido. Deve-se ter cautela ao definir um endpoint como imutável. 

 Alguns clientes de serviço, como o Amazon S3, podem modificar o endpoint retornado pelo resolvedor para determinadas operações de serviço. Por exemplo, o Amazon S3 gerencia automaticamente o [Endereçamento de bucket virtual](https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html) alterando o endpoint resolvido. Você pode evitar que o SDK altere seus endpoints personalizados configurando como. [HostnameImmutable](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint.HostnameImmutable)`true` Por exemplo: 

```
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
    if service == dynamodb.ServiceID && region == "us-west-2" {
        return aws.Endpoint{
            PartitionID:   "aws",
            URL:           "https://test.us-west-2.amazonaws.com",
            SigningRegion: "us-west-2",
            HostnameImmutable: true,
        }, nil
    }
    return aws.Endpoint{}, fmt.Errorf("unknown endpoint requested")
})

cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithEndpointResolverWithOptions(customResolver))
```

## Migração
<a name="migration"></a>

 Ao migrar da v1 para v2 da resolução de endpoint, os seguintes princípios gerais se aplicam: 
+  Retornar um [endpoint](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint) com [HostnameImmutable](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint.HostnameImmutable)set to `false` é aproximadamente equivalente `BaseEndpoint` a configurar o URL originalmente retornado da v1 e deixá-lo `EndpointResolverV2` como padrão. 
+  Retornar um endpoint com HostnameImmutable set to `true` é aproximadamente equivalente à implementação de um `EndpointResolverV2` que retorna a URL originalmente retornada da v1. 
  +  A principal exceção é para operações com prefixos de endpoint modelados. Há uma nota sobre isso mais abaixo. 

 Exemplos desses casos são fornecidos abaixo. 

**Atenção**  
 Os endpoints imutáveis da V1 e a resolução V2 não são equivalentes em comportamento. Por exemplo, substituições de assinatura para recursos personalizados, como o S3 Object Lambda, ainda seriam definidas para endpoints imutáveis retornados por meio do código da v1, mas o mesmo não será feito para a v2. 

### Nota sobre prefixos de host
<a name="note-on-host-prefixes"></a>

 Algumas operações são modeladas com prefixos de host a serem anexados ao endpoint resolvido. Esse comportamento deve funcionar em conjunto com a saída da ResolveEndpoint V2 e, portanto, o prefixo do host ainda será aplicado a esse resultado. 

 Você pode desativar manualmente o prefixo do host do endpoint aplicando um middleware. Consulte a seção de exemplos. 

### Exemplos
<a name="examples-2"></a>

#### Endpoint mutável
<a name="mutable-endpoint"></a>

 O exemplo de código a seguir demonstra como migrar um resolvedor de endpoint básico da v1 que retorna um endpoint modificável: 

```
// v1
client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    o.EndpointResolver = svc.EndpointResolverFromURL("https://custom.endpoint.api/")
})

// v2
client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    // the value of BaseEndpoint is passed to the default EndpointResolverV2
    // implementation, which will handle routing for features such as S3 accelerate,
    // MRAP, etc.
    o.BaseEndpoint = aws.String("https://custom.endpoint.api/")
})
```

#### Endpoint imutável
<a name="immutable-endpoint"></a>

```
// v1
client := svc.NewFromConfig(cfg, func (o *svc.Options) {
    o.EndpointResolver = svc.EndpointResolverFromURL("https://custom.endpoint.api/", func (e *aws.Endpoint) {
        e.HostnameImmutable = true
    })
})

// v2
import (
    smithyendpoints "github.com/aws/smithy-go/endpoints"
)

type staticResolver struct {}

func (*staticResolver) ResolveEndpoint(ctx context.Context, params svc.EndpointParameters) (
        smithyendpoints.Endpoint, error,
    ) {
    // This value will be used as-is when making the request.
    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) {
    o.EndpointResolverV2 = &staticResolver{}
})
```

#### Desativar o prefixo do host
<a name="disable-host-prefix"></a>

```
import (
    "context"
    "fmt"
    "net/url"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/<service>"
    smithyendpoints "github.com/aws/smithy-go/endpoints"
    "github.com/aws/smithy-go/middleware"
    smithyhttp "github.com/aws/smithy-go/transport/http"
)

// disableEndpointPrefix applies the flag that will prevent any
// operation-specific host prefix from being applied
type disableEndpointPrefix struct{}

func (disableEndpointPrefix) ID() string { return "disableEndpointPrefix" }

func (disableEndpointPrefix) HandleInitialize(
    ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler,
) (middleware.InitializeOutput, middleware.Metadata, error) {
    ctx = smithyhttp.SetHostnameImmutable(ctx, true)
    return next.HandleInitialize(ctx, in)
}

func addDisableEndpointPrefix(o *<service>.Options) {
    o.APIOptions = append(o.APIOptions, (func(stack *middleware.Stack) error {
        return stack.Initialize.Add(disableEndpointPrefix{}, middleware.After)
    }))
}

type staticResolver struct{}

func (staticResolver) ResolveEndpoint(ctx context.Context, params <service>.EndpointParameters) (
    smithyendpoints.Endpoint, error,
) {
    u, err := url.Parse("https://custom.endpoint.api/")
    if err != nil {
        return smithyendpoints.Endpoint{}, err
    }

    return smithyendpoints.Endpoint{URI: *u}, nil
}


func main() {
    cfg, err := config.LoadDefaultConfig(context.Background())
    if err != nil {
        panic(err)
    }

    svc := <service>.NewFromConfig(cfg, func(o *<service>.Options) {
        o.EndpointResolverV2 = staticResolver{}
    })

    _, err = svc.<Operation>(context.Background(), &<service>.<OperationInput>{ /* ... */ },
        addDisableEndpointPrefix)
    if err != nil {
        panic(err)
    }
}
```