

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Configuración de puntos de conexión del cliente
<a name="configure-endpoints"></a>

**aviso**  
 La resolución de puntos de conexión es un tema avanzado del SDK. Al cambiar esta configuración, corre el riesgo de invalidar el código. La configuración predeterminada debe poder aplicarse a la mayoría de los usuarios en entornos de producción. 

 AWS SDK para Go Ofrece la posibilidad de configurar un punto final personalizado para usarlo en un servicio. En muchos casos, la configuración predeterminada será suficiente. La configuración de puntos de conexión personalizados permite un comportamiento adicional, como trabajar con versiones previas al lanzamiento de un servicio. 

## Personalización
<a name="customization"></a>

 Existen dos “versiones” de la configuración de resolución de puntos de conexión en el SDK: 
+  v2, publicada en el tercer trimestre de 2023, configurada mediante: 
  +  `EndpointResolverV2` 
  +  `BaseEndpoint` 
+  v1, publicada junto con el SDK, configurada mediante: 
  +  `EndpointResolver` 

 Recomendamos a los usuarios de la resolución de puntos de conexión v1 que migren a la versión 2 para obtener acceso a características del servicio más recientes relacionadas con estos. 

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

 En la versión 2 de la resolución, `EndpointResolverV2` es el mecanismo definitivo a través del cual se produce la resolución de puntos de conexión. El método `ResolveEndpoint` del solucionador se invoca como parte del flujo de trabajo para cada solicitud que realice en el SDK. El nombre de host del `Endpoint` devuelto por el solucionador se usa **tal cual** al realizar la solicitud (sin embargo, los serializadores de operaciones pueden seguir asociando elementos a la ruta HTTP). 

 En la resolución v2 se incluye una configuración adicional de nivel de cliente, `BaseEndpoint`, que se utiliza a fin de especificar un nombre de host “base” para la instancia de su servicio. El valor establecido aquí no es definitivo: se transfiere en última instancia como parámetro al `EndpointResolverV2` del cliente cuando se produce la resolución final (siga leyendo para obtener más información sobre los parámetros `EndpointResolverV2`). La implementación del solucionador tiene entonces la oportunidad de inspeccionar y, posiblemente, modificar ese valor para determinar el punto de conexión final. 

 Por ejemplo, si realiza una solicitud `GetObject` de S3 en un bucket determinado con un cliente en el que ha especificado un `BaseEndpoint`, el solucionador predeterminado inyectará el bucket en el nombre del host si es compatible con el host virtual (suponiendo que no haya desactivado el alojamiento virtual en la configuración del cliente). 

 En la práctica, lo más probable es que `BaseEndpoint` se utilice para dirigir al cliente a una instancia de desarrollo o de vista previa de un servicio. 

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

 Cada servicio toma un conjunto específico de entradas que se transfieren a su función de resolución, definida en cada paquete de servicios como `EndpointParameters`. 

 Cada servicio incluye los siguientes parámetros base, que se utilizan para facilitar la resolución de puntos de conexión general en AWS: 


|  name  |  type  |  description  | 
| --- | --- | --- | 
|  Region  |  string  |  La AWS región del cliente  | 
|  Endpoint  |  string  |  Indica el valor establecido para BaseEndpoint en la configuración del cliente.  | 
|  UseFips  |  bool  |  Indica si los puntos de conexión de FIPS están habilitados en la configuración del cliente.  | 
|  UseDualStack  |  bool  |  Indica si los puntos de conexión de doble pila están habilitados en la configuración del cliente.  | 

 Los servicios pueden especificar parámetros adicionales necesarios para la resolución. Por ejemplo, los `EndpointParameters` de S3 incluyen el nombre del bucket, así como varios ajustes de características específicos de S3 (por ejemplo, si el direccionamiento de host virtual está habilitado). 

 Si implementa su propio `EndpointResolverV2`, no debería tener que crear una instancia propia de `EndpointParameters` en ningún caso. El SDK obtendrá los valores por solicitud y los transferirá a su implementación. 

### Nota acerca de Amazon S3
<a name="a-note-about-amazon-s3"></a>

 Amazon S3 es un servicio complejo con muchas de sus características modeladas a través de complejas personalizaciones de puntos de conexión, como el alojamiento virtual de buckets o el punto de acceso multirregional de S3, entre otras. 

 Por ello, recomendamos que no reemplace la implementación de `EndpointResolverV2` en su cliente de S3. Si necesita ampliar su comportamiento de resolución (por ejemplo, mediante el envío de solicitudes a una pila de desarrollo local con consideraciones adicionales sobre los puntos de conexión), recomendamos encapsular la implementación predeterminada de forma que se delegue de nuevo en esta como alternativa (como se muestra en los ejemplos que aparecen a continuación). 

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

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

 El fragmento de código siguiente muestra cómo apuntar su cliente de S3 a la instancia local de un servicio, que en este ejemplo se aloja en el dispositivo de bucle invertido en el puerto 8080. 

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

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

 El fragmento de código siguiente muestra cómo inyectar un comportamiento personalizado en la resolución de puntos de conexión de S3 mediante `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{
            // ...
        }
    })
}
```

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

 El programa de ejemplo siguiente demuestra la interacción entre `BaseEndpoint` y `EndpointResolverV2`. **Este es un caso de uso avanzado:** 

```
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)
}
```

 Cuando se ejecuta, el programa anterior genera lo siguiente: 

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

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

**aviso**  
 La resolución de puntos de conexión v1 se conserva por motivos de compatibilidad con versiones anteriores y está aislada del comportamiento moderno de la resolución de puntos de conexión v2. Solo se usará si el intermediario establece el campo `EndpointResolver`.   
 Lo más probable es que el uso de la versión 1 le impida acceder a las características del servicio relacionadas con los puntos de conexión que se introdujeron con el lanzamiento de la resolución v2 o después de este. Consulte “Migración” para obtener instrucciones sobre cómo actualizar. 

 A se [EndpointResolver](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointResolver)puede configurar para proporcionar una lógica de resolución de puntos finales personalizada para los clientes del servicio. Puede utilizar un solucionador de puntos de conexión personalizado para reemplazar la lógica de resolución de puntos de conexión de un servicio para todos los puntos de conexión o solo para un punto de conexión regional específico. La resolución de puntos finales personalizada puede activar la lógica de resolución de puntos finales del servicio como alternativa si una resolución personalizada no desea resolver un punto final solicitado. [EndpointResolverWithOptionsFunc](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointResolverWithOptionsFunc)se puede utilizar para agrupar fácilmente las funciones a fin de adaptarlas a la `EndpointResolverWithOptions` interfaz. 

 A se `EndpointResolver` puede configurar fácilmente pasando el solucionador incluido en el [WithEndpointResolverWithOptions](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#WithEndpointResolverWithOptions)paquete [LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig), lo que permite anular los puntos finales al cargar las credenciales, así como configurar el resultado `aws.Config` con un solucionador de puntos final personalizado. 

 El solucionador de puntos de conexión recibe el servicio y la región en forma de cadena, lo que le permite controlar su comportamiento de forma dinámica. Cada paquete de clientes de servicio tiene una constante `ServiceID` exportada que se puede utilizar para determinar qué cliente de servicio invoca el solucionador de puntos de conexión. 

 Un solucionador de terminales puede utilizar el valor del error [EndpointNotFoundError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#EndpointNotFoundError)centinela para activar la resolución alternativa según la lógica de resolución predeterminada del cliente del servicio. Esto permite reemplazar de forma selectiva uno o varios puntos de conexión sin problemas y sin tener que gestionar una lógica alternativa. 

 Si la implementación del solucionador de puntos de conexión devuelve un error distinto de `EndpointNotFoundError`, la resolución de puntos de conexión se detiene y la operación del servicio devuelve un error a la aplicación. 

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

#### Con alternativa
<a name="with-fallback"></a>

 El fragmento de código siguiente muestra cómo se puede reemplazar un único punto de conexión de servicio para DynamoDB con un comportamiento alternativo para otros puntos de conexión: 

```
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))
```

#### Sin alternativa
<a name="without-fallback"></a>

 El fragmento de código siguiente muestra cómo se puede reemplazar un único punto de conexión de servicio para DynamoDB sin un comportamiento alternativo para otros puntos de conexión: 

```
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))
```

### Puntos de conexión inmutables
<a name="immutable-endpoints"></a>

**aviso**  
 Establecer un punto de conexión como inmutable puede impedir que algunas de las características del cliente de servicio funcionen correctamente, lo que podría provocar un comportamiento indefinido. Se debe tener cuidado a la hora de definir un punto de conexión como inmutable. 

 Algunos clientes de servicio, como Amazon S3, pueden modificar el punto de conexión devuelto por el solucionador para determinadas operaciones de servicio. Por ejemplo, Amazon S3 gestionará de forma automática el [direccionamiento virtual de buckets](https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html) al mutar el punto de conexión resuelto. Puedes evitar que el SDK modifique tus puntos de conexión personalizados configurándolos en. [HostnameImmutable](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint.HostnameImmutable)`true` Por ejemplo: 

```
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))
```

## Migración
<a name="migration"></a>

 Al migrar de la versión 1 a la versión 2 de la resolución de puntos de conexión, se aplican los siguientes principios generales: 
+  Devolver un [punto final](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint) con el valor [HostnameImmutable](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Endpoint.HostnameImmutable)establecido en `false` equivale aproximadamente `BaseEndpoint` a configurarlo en la URL devuelta originalmente desde la versión 1 y dejarlo `EndpointResolverV2` como predeterminado. 
+  Devolver un punto final con el valor HostnameImmutable establecido en `true` equivale aproximadamente a implementar un punto final `EndpointResolverV2` que devuelva la URL devuelta originalmente desde la versión 1. 
  +  La excepción principal se da en el caso de las operaciones con prefijos de punto de conexión modelados. Más adelante se incluye una nota al respecto. 

 A continuación, se proporcionan ejemplos de estos casos. 

**aviso**  
 Los puntos de conexión inmutables de la versión 1 y la resolución de la versión 2 no tienen un comportamiento equivalente. Por ejemplo, los reemplazos de firma para características personalizadas como S3 Object Lambda seguirían estableciéndose para los puntos de conexión inmutables devueltos mediante código de la versión 1, pero no se haría lo mismo en el caso de la versión 2. 

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

 Algunas operaciones se modelan con prefijos de host que se anteponen al punto de conexión resuelto. Este comportamiento debe funcionar en conjunto con el resultado de la ResolveEndpoint V2 y, por lo tanto, el prefijo de host se seguirá aplicando a ese resultado. 

 Puede deshabilitar el prefijo de host del punto de conexión de forma manual mediante la aplicación de un middleware (consulte la sección de ejemplos). 

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

#### Punto de conexión mutable
<a name="mutable-endpoint"></a>

 En el ejemplo de código siguiente se muestra cómo migrar un solucionador de puntos de conexión básico de la versión 1 que devuelve un punto de conexión modificable: 

```
// 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/")
})
```

#### Punto de conexión inmutable
<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{}
})
```

#### Deshabilitación del prefijo de 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)
    }
}
```