Go SDK Integration Guide
This topic explains how to integrate HTTPDNS using the Go SDK. For the basic principles of HTTPDNS integration, see Client Integration Overview.
1. Quick Start
1.1 Enable the Service
You can enable HTTPDNS by following the Quick Start.
1.2 Get Configuration Information
In the EMAS console, go to Development Settings and obtain your AccountId, SecretKey, and AESSecretKey. For more information, see Development Settings. You need these values to initialize the SDK.
2. Installation
You can install the SDK using `go get`:
go get github.com/aliyun/alicloud-httpdns-go-sdk/pkg/httpdnsIntegration examples:
See the sample code and documentation in the GitHub repository.
3. Configure and Use the SDK
3.1 Initialization Configuration
You must initialize the SDK after your application starts and before you can use HTTPDNS features. During initialization, set parameters such as AccountId and SecretKey, and enable or disable features. Example:
package main
import (
"context"
"log"
"os"
"github.com/aliyun/alicloud-httpdns-go-sdk/pkg/httpdns"
)
func main() {
config := httpdns.DefaultConfig()
config.AccountID = "your-account-id"
config.SecretKey = "your-secret-key" // Optional. Required for authenticated resolution.
config.EnableHTTPS = true // Set to true to use HTTPS.
client, err := httpdns.NewClient(config)
if err != nil {
log.Fatal(err)
}
defer client.Close()
}If you set EnableHTTPS to true, your billing increases. Carefully read the Product Billing document.
3.1.1 Configure Logging
To log HTTPDNS events during development, configure a Logger when initializing the SDK. Example:
config := httpdns.DefaultConfig()
config.Logger = log.New(os.Stdout, "[HTTPDNS] ", log.LstdFlags)3.2 Resolve Domain Names
3.2.1 Synchronous Resolution
The synchronous method first returns cached results. If no cache hit occurs, the method sends an HTTP request. Example:
func resolve(client httpdns.Client) {
ctx := context.Background()
result, err := client.Resolve(ctx, "www.aliyun.com")
if err != nil {
log.Printf("Resolution failed: %v", err)
return
}
log.Printf("Domain: %s", result.Domain)
log.Printf("IPv4: %v", result.IPv4)
log.Printf("IPv6: %v", result.IPv6)
log.Printf("TTL: %v", result.TTL)
}3.2.2 Asynchronous Resolution
You can use asynchronous resolution for non-blocking calls. The callback function returns the result. Example:
func asyncResolve(client httpdns.Client) {
ctx := context.Background()
client.ResolveAsync(ctx, "www.aliyun.com", func(result *httpdns.ResolveResult, err error) {
if err != nil {
log.Printf("Asynchronous resolution failed: %v", err)
return
}
log.Printf("Asynchronous resolution result: %s -> %v", result.Domain, result.IPv4)
})
}3.2.3 Batch Resolution
You can use batch resolution to resolve multiple domain names at once. Example:
func batchResolve(client httpdns.Client) {
ctx := context.Background()
domains := []string{"www.aliyun.com", "www.taobao.com", "www.tmall.com"}
results, err := client.ResolveBatch(ctx, domains)
if err != nil {
log.Printf("Batch resolution failed: %v", err)
return
}
for _, result := range results {
log.Printf("Domain: %s, IPv4: %v", result.Domain, result.IPv4)
}
}Each batch resolution supports up to five domain names. Requests that include more than five domains return an error.
4. Go Best Practices
Customize the DialContext function to integrate HTTPDNS resolution seamlessly into the standard net/http client. This integration supports both HTTP and HTTPS requests.
Step 1: Create an HTTPDNS Client
package main
import (
"context"
"fmt"
"log"
"net"
"net/http"
"os"
"time"
"github.com/aliyun/alicloud-httpdns-go-sdk/pkg/httpdns"
)
func main() {
// Create an HTTPDNS client.
config := httpdns.DefaultConfig()
config.AccountID = "your-account-id"
config.SecretKey = "your-secret-key"
config.Logger = log.New(os.Stdout, "[HTTPDNS] ", log.LstdFlags)
dnsClient, err := httpdns.NewClient(config)
if err != nil {
log.Fatal(err)
}
defer dnsClient.Close()
// Create an HTTP client that uses HTTPDNS.
httpClient := createHTTPDNSClient(dnsClient)
// Send a request.
resp, err := httpClient.Get("https://www.aliyun.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Printf("Status: %s\n", resp.Status)
}Step 2: Create a Custom HTTP Client
func createHTTPDNSClient(dnsClient httpdns.Client) *http.Client {
return &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
// Parse the host and port.
host, port, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
// Resolve the domain name using HTTPDNS.
result, err := dnsClient.Resolve(ctx, host)
if err != nil {
log.Printf("[DNS Lookup] HTTPDNS resolution failed. Falling back to system DNS: %s, error: %v", host, err)
return net.Dial(network, addr)
}
// Prefer IPv4.
var resolvedIP string
if len(result.IPv4) > 0 {
resolvedIP = result.IPv4[0].String()
log.Printf("[DNS Lookup] HTTPDNS resolution succeeded: %s -> %s (IPv4)", host, resolvedIP)
} else if len(result.IPv6) > 0 {
resolvedIP = result.IPv6[0].String()
log.Printf("[DNS Lookup] HTTPDNS resolution succeeded: %s -> %s (IPv6)", host, resolvedIP)
} else {
log.Printf("[DNS Lookup] HTTPDNS returned no IP addresses. Falling back to system DNS: %s", host)
return net.Dial(network, addr)
}
// Connect using the resolved IP address.
return net.Dial(network, net.JoinHostPort(resolvedIP, port))
},
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
DisableCompression: false,
},
}
}5. API Reference
5.1 Initialization
The configuration is initialized when the application starts.
config := httpdns.DefaultConfig()
config.AccountID = "your-account-id"
config.SecretKey = "your-secret-key"
client, err := httpdns.NewClient(config)
if err != nil {
log.Fatal(err)
}
defer client.Close()Parameters:
Parameter Name | Type | Is it required? | feature |
AccountID | string | Required parameters | Account ID |
SecretKey | string | Optional parameters | Signing key |
BootstrapIPs | []string | Optional parameter | A list of bootstrap IP addresses. |
Timeout | time.Duration | Optional parameters | Resolution timeout. Default: 5 seconds. |
MaxRetries | int | Optional parameters | Maximum number of retries. Default: 0. |
EnableHTTPS | bool | Optional parameters | Set to true to use HTTPS. Default: false. |
EnableMetrics | bool | Optional parameters | Set to true to enable metrics collection. Default: false. |
EnableMemoryCache | bool | Optional parameter | Set to true to enable memory caching. Default: true. |
EnablePersistentCache | bool | Optional parameters | Set to true to enable persistent caching. Default: false. |
AllowExpiredCache | bool | Optional parameters | Set to true to allow expired cache entries. Default: false. |
CacheExpireThreshold | time.Duration | Optional parameters | Expiration threshold for persistent cache entries. Default: 0. |
Logger | Logger | Optional parameters | Logger |
5.2 Resolve a Domain Name
Resolves a specified domain name.
ctx := context.Background()
result, err := client.Resolve(ctx, "www.aliyun.com")
if err != nil {
log.Printf("Resolution failed: %v", err)
return
}
fmt.Printf("IPv4: %v\n", result.IPv4)
fmt.Printf("IPv6: %v\n", result.IPv6)Parameters:
Parameter Name | Type | Required | Features |
ctx | context.Context | Required parameter | The context for the operation. |
domain | string | This parameter is required. | domain name |
opts | ...ResolveOption | Optional parameters | Resolution options. |
Resolution options:
Option Function | Features |
WithIPv4Only() | Resolve IPv4 addresses only. |
WithIPv6Only() | Resolve IPv6 addresses only. |
WithBothIP() | Resolve both IPv4 and IPv6 addresses. |
WithTimeout(duration) | Set the timeout duration. |
WithClientIP(ip) | Set the client IP address for proximity-based routing. |
Return fields:
Field name | Type | Features |
Domain | string | The domain name. |
ClientIP | string | The client IP address. |
IPv4 | []net.IP | A list of IPv4 addresses. |
IPv6 | []net.IP | A list of IPv6 addresses. |
TTL | time.Duration | The time-to-live value. |
Source | ResolveSource | Parsing source |
Timestamp | time.Time | Parsing timestamps |
5.3 Batch Resolution
Resolves multiple domain names at once.
ctx := context.Background()
domains := []string{"www.aliyun.com", "www.taobao.com"}
results, err := client.ResolveBatch(ctx, domains)
if err != nil {
log.Printf("Batch resolution failed: %v", err)
return
}
for _, result := range results {
fmt.Printf("Domain: %s, IPv4: %v\n", result.Domain, result.IPv4)
}Parameters:
Parameter Name | Type | Is this required? | Features |
ctx | context.Context | Required parameters | The context for the operation. |
domains | []string | Required parameter | A list of domain names. Maximum: 5. |
opts | ...ResolveOption | Optional parameter | Resolution options. |
5.4 Asynchronous Resolution
Resolves domain names asynchronously. The callback function returns the result.
ctx := context.Background()
client.ResolveAsync(ctx, "www.aliyun.com", func(result *httpdns.ResolveResult, err error) {
if err != nil {
log.Printf("Asynchronous resolution failed: %v", err)
return
}
fmt.Printf("Resolution result: %v\n", result.IPv4)
})Parameters:
Parameter name | Type | Required | feature |
ctx | context.Context | Required parameters | The context for the operation. |
domain | string | Required parameters | The domain name to resolve. |
callback | func(*ResolveResult, error) | Required parameters | The callback function. |
opts | ...ResolveOption | Optional parameters | Resolution options. |
5.5 Client Management
Checks the client status and manages its lifecycle.
// Check client health.
isHealthy := client.IsHealthy()
// Get the current service IP addresses.
serviceIPs := client.GetServiceIPs()
// Manually update service IP addresses.
err := client.UpdateServiceIPs(ctx)
// Get metrics.
stats := client.GetMetrics()
fmt.Printf("Total resolutions: %d\n", stats.TotalResolves)
fmt.Printf("Success rate: %.2f%%\n", stats.SuccessRate*100)
fmt.Printf("Average latency: %v\n", stats.AvgLatency)
// Reset metrics.
client.ResetMetrics()
// Close the client.
err := client.Close()6. Summary
This topic describes how to use the HTTPDNS Go SDK and best practices for integrating it into your applications. By customizing DialContext, you can integrate HTTPDNS into your HTTP client to achieve high-performance and highly available domain name resolution. Key features include the following:
Easy to use: Provides synchronous, asynchronous, and batch domain name resolution APIs.
High availability: Includes built-in caching and fallback strategies.
Secure and reliable: Supports authenticated domain name resolution and HTTPS communication.
Follow the best practices in this topic to efficiently integrate HTTPDNS into your Go applications.